linux的write是线程安全的吗,socket的write/send还是是否是线程安全?
在多線程的網(wǎng)絡(luò)服務(wù)器程序中, 對同一個客戶端多線程同時發(fā)送數(shù)據(jù)是經(jīng)常可能發(fā)生的事情, 也就是有可能會多
線程的對一個fd調(diào)用send/write, 那么這種操作是否需要加鎖?并發(fā)寫套接字是否導(dǎo)致系統(tǒng)緩沖區(qū)數(shù)據(jù)混亂呢? 網(wǎng)上搜
了下,有人說可以寫,有人說不能,linux man page也沒有說明。 看來需要寫程序測試。 寫了個server的代碼進(jìn)行
測試。
10個線程同時對一個fd進(jìn)行write, 看看客戶端會收到什么數(shù)據(jù)。
服務(wù)端代碼:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int sockfd;
inline void mysend(const char *s) {
const char *s = (const char*)p;
printf("written %d\n", write(sockfd, s, strlen(s)));
}
void *func1(void *p) {
mysend(p);
return 0;
}
void *func2(void *p) {
mysend(p);
return 0;
}
void *func3(void *p) {
mysend(p);
return 0;
}
void *func4(void *p) {
mysend(p);
return 0;
}
void *func5(void *p) {
mysend(p);
return 0;
}
void *func6(void *p) {
mysend(p);
return 0;
}
void *func7(void *p) {
mysend(p);
return 0;
}
void *func8(void *p) {
mysend(p);
return 0;
}
void *func9(void *p) {
mysend(p);
return 0;
}
void *func10(void *p) {
mysend(p);
return 0;
}
void *(*funcArray[])(void*) = { func1, func2, func3,func4,func5,func6,func7,func8,func9,func10 };
const char *paramArray[] = {"11111111111111111111111111111111", "22222222222222222222222222222222222222222222222222",
"Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "Bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"Cccccccccccccccccccccccc", "Ddddddddddddddddddddd", "Eeeeeeeeeeeeeeeeeee", "Fffffffffffffffffffffff",
"Ggggggggggggggggggggggggg", "Oooooooooooooooooooooooooooooooooooooooooooooooooooo" };
int main() {
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &sa, 0 );
char recvbuf[RECV_BUF_LEN];
struct sockaddr_in addr;
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("error.");
return 0;
}
int val = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(6666);
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
listen(fd, 100);
while (true) {
struct sockaddr_in cli_addr;
socklen_t socklen = sizeof(cli_addr);
sockfd = accept(fd, (struct sockaddr*)&cli_addr, &socklen);
if (fd == -1) {
perror("accept");
exit(0);
}
printf("accept new connection : %d\n", fd);
pthread_t tt[10];
for (int i = 0; i < 10; ++i) {
pthread_create(&tt[i],NULL, funcArray[0], (void*)paramArray[i]);
}
for (int i = 0; i < 10; ++i) {
pthread_join(tt[i], NULL);
}
printf("done\n");
}
return 0;
}
客戶端用python簡單寫個測試程序
from socket import *
import time
sock = socket(AF_INET, SOCK_STREAM, 0)
sock.connect(('192.168.42.128', 3333))
while True:
recvbuf = sock.recv(1024)
print recvbuf
time.sleep(1)
反復(fù)執(zhí)行程序會發(fā)現(xiàn), 客戶端收到的數(shù)據(jù)段,重復(fù)數(shù)據(jù)全部是連續(xù)的, 沒有一次非連續(xù)數(shù)據(jù)出現(xiàn), 這已經(jīng)說明,操作系統(tǒng)在write/send的時候,會對socket的寫緩沖區(qū)加鎖。其實(shí)無論是linux還是windows,Socket都是線程安全的。
所以程序不用擔(dān)心也不需要對套接字進(jìn)行同步了。
總結(jié)
以上是生活随笔為你收集整理的linux的write是线程安全的吗,socket的write/send还是是否是线程安全?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux网络管理技术,linux网络管
- 下一篇: linux 文件系统 vfs,linux