当我在Linux上创建套接字时,可以在创建时指定标志O_CLOEXEC
:
auto fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
所以没有办法,其他一些线程会在此套接字保持打开的情况下执行fork()
+ exec()
。
但在Mac上,根据手册,我不能做同样的伎俩:
套接字具有指示的类型,它指定通信的语义。 目前定义的类型是: SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM
只能通过调用O_CLOEXEC
来设置标记fcntl()
。并且它不是原子方式 - 某些线程在调用exec()
和socket()
之间可能会fcntl()
。
如何解决此问题?
答案 0 :(得分:-1)
此处需要同步。
换行socket()
和fork()
并创建一个互斥锁,使系统的fork()
不被执行,而另一个线程位于调用系统之间的关键部分。 s socket()和fcntl()
。
伪代码:
mutex_t m = mutex_init(...);
int socket_wrapper(...)
{
lock(m);
int sd = socket(..);
fcntl(sd, O_CLOEXEC);
unlock(m);
return sd;
}
pid_t fork_wrapper(void)
{
lock(m);
pid_t pid = fork();
unlock(m)
return pid;
}