2010-03-01 104 views
15

我正在使用Linux和Win32套接字API。在我的程序中,多个线程共享一个套接字句柄。特别地,多个线程使用共享的套接字句柄(即,相同的端口)调用send。在这种情况下,我是否必须锁定线程安全性?我无法找到答案。我可以做一个测试,但想听听你的经验。C socket API是线程安全的吗?

EDIT:我知道通过套接字发送数据根本不是原子操作。当然,我们必须使用互斥体来保证线程安全。但是,我想知道系统API是否可以拥有自己的内部锁。如果是这样,我们可以省略把自己的锁。

此问题也适用于fprintf函数。我想知道这样的系统API会拥有自己的锁。根据我的经验,从多个线程调用fprintf并没有杀死我的程序,尽管文件或stdout上有比赛(即不一致或不可预知的输出,但程序没有崩溃),这暗示fprintf有一个锁来保护它们的内部数据结构。

+0

在我看来,多线程读取和写入同一个套接字是事实上的设计问题。 – theMayer 2018-02-12 20:10:33

回答

0

通过套接字发送数据不是原子事务 - 任何非原子事务都需要锁定/同步。这与平台无关。

+1

谢谢。是的,我知道这根本不是原子操作。但是,我想知道系统API是否可以拥有自己的内部锁。 – minjang 2010-03-01 07:56:05

+4

但是,如果他们这样做,将使他们原子... – EJP 2010-03-01 08:01:36

11

套接字不是C++标准的一部分,因此它取决于实现。通常它们不是线程安全的,因为send不是原子操作。请参阅this discussion了解更多信息。

编辑:操作系统可能有或没有内部锁保护内部结构。这取决于实施。所以你不应该指望它。

+0

听起来像POSIX发送/ recv是线程安全的基于您的链接和本次讨论:http://stackoverflow.com/a/1981439/602245 – Brett 2013-02-10 17:46:19

0

不,接受创建的变量不需要互斥。线程使用的任何数据至少应该是信号量。

sem_t* sem_data; 
2

我发现多个socket close()文件描述符调用在并发环境中非常危险。

通常会忽略多个调用,但在其他线程打开另一个文件描述符的情况下,通常它会获取以前的文件描述符,并开始恶梦。