管道的三種使用方案中,唯一正確而安全的使用方法

2021-07-10 17:13:15 字數 2972 閱讀 7555

系統自帶的管道方法:

全域性變數:

nspipe * pipe = [nspipe pipe] ;

nsfilehandle *pipereadhandle = [pipe filehandleforreading] ;

int pipereadfd = [[pipe filehandleforreading] filedescriptor], fd];

int pipewritefd = [[pipe filehandleforwriting] filedescriptor], fd];

寫管道處,注意這個函式是無返回的函式,無法判斷管道異常:

[self.pipewritefd writedata: [@」send」 datausingencoding: nsasciistringencoding]]; 見我的文章管道,訊號量,共享記憶體,socket的實際使用場景和nspipe管道的使用 (

它的缺點也很顯然,執行緒被殺,管道資源被**時,你訪問該管道,會出現管道破裂的系統級崩潰。詳細見我的文章。

signal 13 was raised(sigpipe管道破裂)

所以還時用系統級別的管道最安全,可以通過寫管道是否可以寫來判斷管道是否可用。

這樣使用申請管道也是錯誤的,因為你的執行緒申請的管道,在外部要可以用,肯定要能用,你申請個區域性變數,等你離開執行緒時,你再使用管道,你就訪問了空指標,造成管道破裂崩潰。下面是例子

int pipesno[2];

pipesno[0] = -1;

pipesno[1] = -1;

pipe(pipesno);

self.fdguardmodifywaittimereadpipe = pipesno[0];

self.fdguardmodifywaittimewritepipe = pipesno[1];

int set = 1;

setsockopt(self.fdguardmodifywaittimereadpipe, sol_socket, so_nosigpipe, (void *)&set, sizeof(int));

int write = 1;

setsockopt(self.fdguardmodifywaittimewritepipe, sol_socket, so_nosigpipe, (void *)&write, sizeof(int));

看來你向獲得強大的功能,那麼你就要從作業系統層做起,並且自己負責管道的申請和釋放,不受系統arc自動管理記憶體控制。下面是正確而強大的使用管道的部分例子,

申請管道部分:

if(self.fdguardpipehead != nil)

self.fdguardpipehead = malloc(2 * sizeof(int));

_fdguardpipehead[0] = -1;

_fdguardpipehead[1] = -1;

pipe(_fdguardpipehead);

self.fdguardmodifywaittimereadpipe = _fdguardpipehead[0];

self.fdguardmodifywaittimewritepipe = _fdguardpipehead[1];

int set = 1;

setsockopt(self.fdguardmodifywaittimereadpipe, sol_socket, so_nosigpipe, (void *)&set, sizeof(int));

int write = 1;

setsockopt(self.fdguardmodifywaittimewritepipe, sol_socket, so_nosigpipe, (void *)&write, sizeof(int));

[self creatsocketconnection];

傳送於異常判斷

//通過長連線的監控管道傳送char *格式的訊息

-(bool)sendmessagebysocketmonitorpipewithchararr : (const char *)message

unsigned char input_msg[buffer_size] = ;

memcpy(input_msg, message, len);;

@try

else }

@catch (n***ception *exception)

@finally 關閉管道的操作

-(void)processsocketpipeclosed

self.socketthreadpipehead = malloc(2 * sizeof(int));

_socketthreadpipehead[0] = -1;

_socketthreadpipehead[1] = -1;

pipe(_socketthreadpipehead);

self.fdreadpipe = _socketthreadpipehead[0];

self.fdwritepipe = _socketthreadpipehead[1];

int setpipe = 1;

setsockopt(self.fdreadpipe, sol_socket, so_nosigpipe, (void *)&setpipe, sizeof(int));

int writepipe = 1;

setsockopt(self.fdwritepipe, sol_socket, so_nosigpipe, (void *)&writepipe, sizeof(int));

if(![self sendmessagebypipewithchararr : g_guardthreadcheckifnormal])

self.socketconnectstat = sockect_connect_abnormal;

}else

使用memcache處理快取的三種方案

這篇文章主要討論的問題是 如何為專案設計乙個完整而簡潔的快取系統。只講做法,不講原理。在我們專案中,使用到了三種方法,來保證了快取系統的有效簡潔。1 第一種,最常見的方式 讀取資料的主要步驟如下 1 先從快取中獲取資料 如果在快取中獲取到,則直接返回已獲取的資料 2 如果獲取不到,再從資料庫裡面讀取...

使用memcache處理快取的三種方案

這篇文章主要討論的問題是 如何為專案設計乙個完整而簡潔的快取系統。只講做法,不講原理。在我們專案中,使用到了三種方法,來保證了快取系統的有效簡潔。1 第一種,最常見的方式 讀取資料的主要步驟如下 1 先從快取中獲取資料 如果在快取中獲取到,則直接返回已獲取的資料 2 如果獲取不到,再從資料庫裡面讀取...

PHP生成唯一ID的三種方法

1 md5 time mt rand 1,1000000 這種方法有一定的概率會出現重複 2 php內建函式uniqid uniqid 函式基於以微秒計的當前時間,生成乙個唯一的 id.w3school參考手冊有一句話 由於基於系統時間,通過該函式生成的 id 不是最佳的。如需生成絕對唯一的 id,...