假設我有2個進程ProcessA和ProcessB。如果我在ProcessA中執行int fd=open(somefile)
,那麼我可以通過IPC將文件描述符fd
的值傳遞給ProcessB,並讓它處理相同的文件?我可以在Linux上共享一個文件描述符到另一個進程嗎?還是他們在進程本地?
回答
您可以通過unix domain套接字將文件描述符傳遞給另一個進程。 這裏是通過這樣一個文件描述符的代碼,從Unix Network Programming
ssize_t
write_fd(int fd, void *ptr, size_t nbytes, int sendfd)
{
struct msghdr msg;
struct iovec iov[1];
#ifdef HAVE_MSGHDR_MSG_CONTROL
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = CMSG_FIRSTHDR(&msg);
cmptr->cmsg_len = CMSG_LEN(sizeof(int));
cmptr->cmsg_level = SOL_SOCKET;
cmptr->cmsg_type = SCM_RIGHTS;
*((int *) CMSG_DATA(cmptr)) = sendfd;
#else
msg.msg_accrights = (caddr_t) &sendfd;
msg.msg_accrightslen = sizeof(int);
#endif
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return(sendmsg(fd, &msg, 0));
}
/* end write_fd */
採取下面是接收文件描述符
ssize_t
read_fd(int fd, void *ptr, size_t nbytes, int *recvfd)
{
struct msghdr msg;
struct iovec iov[1];
ssize_t n;
int newfd;
#ifdef HAVE_MSGHDR_MSG_CONTROL
union {
struct cmsghdr cm;
char control[CMSG_SPACE(sizeof(int))];
} control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
#else
msg.msg_accrights = (caddr_t) &newfd;
msg.msg_accrightslen = sizeof(int);
#endif
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ((n = recvmsg(fd, &msg, 0)) <= 0)
return(n);
#ifdef HAVE_MSGHDR_MSG_CONTROL
if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL &&
cmptr->cmsg_len == CMSG_LEN(sizeof(int))) {
if (cmptr->cmsg_level != SOL_SOCKET)
err_quit("control level != SOL_SOCKET");
if (cmptr->cmsg_type != SCM_RIGHTS)
err_quit("control type != SCM_RIGHTS");
*recvfd = *((int *) CMSG_DATA(cmptr));
} else
*recvfd = -1; /* descriptor was not passed */
#else
/* *INDENT-OFF* */
if (msg.msg_accrightslen == sizeof(int))
*recvfd = newfd;
else
*recvfd = -1; /* descriptor was not passed */
/* *INDENT-ON* */
#endif
return(n);
}
/* end read_fd */
代碼
您可以使用此線程所描述的方法號,或(更常規)的方式,通過在相關進程(通常是父 - 子或同級)之間共享它,分叉進程會自動接收一個副本。
實際上,分叉進程可以獲得所有的FD並可以使用它們,除非它們關閉它們(這通常是個好主意)。
因此,如果父母派生兩個孩子,如果他們都有一個文件描述符他們沒有關閉,它現在被共享(即使父母隨後關閉它)。例如,這可能是從一個孩子到另一個孩子的管道。這就是外殼重定向的方式
ls -l | more
工作。
注意,在上面的例子中,變量的設置接收時,如:
msg.msg_name = NULL;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
不是必需的。帶有標題的消息結構的全部概念是,接收站點不必知道它讀取的內容,並且可以通過檢查(第一個)標題,它是什麼類型的消息以及期望的內容。
雖然技術上是正確的,但在這種情況下指定緩衝區有一個很好的理由:爲了發送OOB消息(套接字控制消息在這種情況下),您需要指定一個非空消息(請參閱unix_stream_sendmsg,例如http://lxr.free-electrons.com/source/net/unix/af_unix.c#L1836)。當沒有iovec的時候,Linux會一遍又一遍地傳遞這個消息。因此,要讀取多個OOB消息,您必須在某個時刻讀取消息數據。 – Michael 2017-01-05 18:26:59
如果兩個進程屬於同一個用戶,那麼您可以簡單地使用procfs。
char fd_path[64]; // actual maximal length: 37 for 64bit systems
snprintf(fd_path, sizeof(fd_path), "/proc/%d/fd/%d", SOURCE_PID, SOURCE_FD);
int new_fd = open(fd_path, O_RDWR);
當然,您需要一些IPC機制來共享SOURCE_FD
的值。見例如「Linux C: upon receiving a signal, is it possible to know the PID of the sender?」。
- 1. 跨進程共享文件描述符
- 2. 文件描述符是在Unix上是其本地進程還是全局文件描述符
- 3. 在Linux上,進程是否可以呈現另一個進程的GUI?
- 4. Linux中另一個進程的重複文件描述符(不帶sendmsg)
- 5. 我可以有一個Maven程序集描述符依賴於另一個嗎?
- 6. 我們可以將我們的代碼注入到另一個子進程嗎?
- 7. 不希望父進程和子進程共享同一個文件描述符表
- 8. C中調用一個二進制文件(同時共享文件描述符)
- 9. 進程VS線程:兩個進程可以共享相同的共享內存嗎?可以兩個線程?
- 10. 在線程之間共享相同的epoll文件描述符可以嗎?
- 11. 是文件描述符表自我維護每個進程
- 12. 可以將變量從一個進程傳遞到另一個進程嗎?
- 13. 父進程和子進程共享一個IPC共享內存
- 14. 在幾個進程間共享一個文件[Perl]
- 15. 在fork之後,父進程和子進程是否共享由管道創建的文件描述符?
- 16. 一個進程寫入,另一個進程讀取共享內存
- 17. 在兒童完成一個exec之後與子進程共享文件描述符表
- 18. 在不同進程之間共享打開的文件描述符
- 19. 我們可以共享一個.eslintignore文件在回購
- 20. 一個進程可以使用另一個進程創建的套接字嗎?
- 21. IPC可以通過一個進程破壞另一個進程嗎?
- 22. Linux:是否可以在進程之間共享代碼?
- 23. 多個JVM進程可以共享公共類的內存嗎?
- 24. 我們可以在應用程序域共享一個靜態字段嗎?
- 25. 文件描述符和進程關係
- 26. Python線程可以在同一個進程上工作嗎?
- 27. 我可以在共享項目上本地刪除一個phpmyadmin數據庫嗎?
- 28. 找到哪個進程在linux中產生另一個進程的方法?
- 29. 我可以修改另一個進程的UID嗎?
- 30. 我可以從另一個進程卸載DLL嗎? (Win32)
Duplicate:http://stackoverflow.com/questions/1997622 – Zitrax 2010-03-01 22:21:17
請參閱[這個問題](http://stackoverflow.com/questions/1997622)。 – bmargulies 2010-03-01 20:10:21