Linux下進程間傳遞描述符
每個進程都有自己的進程空間,這使得描述符在進程間傳遞變得不容易。
就比如說Linux下提供進程間傳遞描述符的機制,但是卻要求兩個進程是父子進程。
linux進程間傳遞描述符的機制是通過sendmsg和recvmsg兩個函數實現的;
該機制可以傳遞任意形式的描述符,如pipe、open、mkfifo、socket、accept等;
機制的原理:
1、進程間傳遞的描述符在內核層面實際上是同一個描述符,只是內核對該描述符的引用標記是+n的,每發送一次,引用次數+1;
//描述符傳遞給多個進程,但是如果其中一個進程修改了描述符的屬性(如socket的同步/異步),那麼所有進程的描述符的屬性都被改變了;
2、每close一個描述符(發送了多個進程,每個進程都需要close)都會在內核層面對該描述符的引用次數進行-1操作;
需要注意的地方:
1、在使用centos6.5環境下開發的過程中,發現socket描述符傳遞機制存在一點問題。從父進程發送描述符到子進程接收這個過程中,內核層面描述符的引用次數並沒有立即+1。
2、我用父進程異步發送描述符,子進程接受描述符,但是如果父進程做完處理之後,過早close描述符,子進程接收到的描述符僅是一個int型數據,並不是可以使用的描述符。
相關數據結構:
首先的介紹recvmsg和sendmsg的函數調用形式
ssize_t recvmsg(int sockfd, struct msghdr*msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr*msg, int flags);
msghdr等結構體的定義如下:
struct iovec {
void *iov_base;
size_t iov_len;
}
struct msghdr {
void msg_name;
socklen_t msg_namelen;
struct iovec *msg_iov;
size_t msg_iovlen;
void *msg_control; //用於傳遞描述符的輔數據
size_t msg_controllen;
int msg_flags;
}
不過需要注意的是,有時候我們僅需要發送描述符,但是我們不能不發送實際數據!可以隨便發送一個char當做實際數據;
因爲recvmsg和sendmsg的示例代碼網上一搜一大把,因此這些代碼在這裏我就不貼了;