Linux套接字和multithreading程序

我必须编写使用Unix数据报套接字的简单的客户端 – 服务器应用程序。 客户端可以根据服务器的请求向服务器发送信息,也可以根据自己的请求从服务器接收信息。

我有一个想法,一个线程将等待用户input,它决定了我们要发送到服务器的请求,另一个线程将等待来自服务器的套接字消息,如果它是我们所要求的消息将把它写到标准输出,如果是服务器请求线程会写什么服务器请求。 我会使用互斥锁,以便两个线程不会同时写入同一个套接字。

我的问题是,如果一个线程将从某个套接字读取,同时其他线程将使用相同的套接字发送数据,套接字将如何performance,是否安全? 或者我应该使用互斥这种情况呢?

内核结构通常以线程安全的方式构建; 套接字也不例外。 如果你担心什么,不是使用套接字和线程的安全,而是程序的逻辑。

此外,我想提到的是,流套接字是全双工的,这意味着保证读/写安全地同时发生,这将如何发生? 内核会为您锁定,或者确保您可以同时进行发送和接收。

对于全双工参数:
http://www.kernel.org/doc/man-pages/online/pages/man2/socket.2.html对于内核结构是线程安全的:
我找不到支持这个链接的链接,但是我对此有99%的把握。

PS如果有疑问,测试的东西可能会有所帮助
编辑:
如果我说的是错的,请在投票前对它进行评论。

编辑.2:
在这里你可以发现,POSIX标准规定它的所有函数都必须是线程安全的,除了2.9.1
http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html

在Linux和Windows中,send()和recv()调用(通常用于TCP,但我认为也可以用于UDP),可能会提前返回而不发送您想要发送的全部数据量。 这将导致线程问题,因为你的消息将分裂。

我发现使用以下属性包装recv()和send()函数是最简单的:

  • 只有在我们请求的所有数据被写入套接字后才会返回
  • 线程安全

然后在所有使用send / recv的地方使用这个包装器。

这里是包装的代码(随意更改错误处理):

//linux (must change SOCKET types to int) //#include <sys/socket.h> //windows //#include <Winsock2.h> //#include <ws2tcpip.h> //blocks until the full amount of bytes requested are read //thread safe //throws exception on error void recv_bytes(SOCKET socket, char* buf, int len, int flags){ static std::mutex mtx; mtx.lock(); int bytes_received = 0; while (bytes_received != len){ int bytes = recv(socket, buf + bytes_received, len - bytes_received, flags); //error check if (bytes == 0){ throw std::exception("Network Exception"); } bytes_received += bytes; } mtx.unlock(); } //blocks until the full amount of bytes requested are sent //thread safe //throws exception on error void send_bytes(SOCKET socket, char* buf, int len, int flags){ static std::mutex mtx; mtx.lock(); int bytes_sent = 0; while (bytes_sent != len){ int bytes_s0 = send(socket, buf, len, flags); if (bytes_sent == SOCKET_ERROR) { mtx.unlock(); throw std::exception("Network Exception"); } bytes_sent += bytes_s0; } mtx.unlock(); }