linux的write是线程安全的吗,socket的write/send还是是否是线程安全?

在多线程的网络服务器程序中, 对同一个客户端多线程同时发送数据是经常可能发生的事情, 也就是有可能会多

线程的对一个fd调用send/write, 那么这种操作是否需要加锁?并发写套接字是否导致系统缓冲区数据混乱呢? 网上搜

了下,有人说可以写,有人说不能,linux man page也没有说明。 看来需要写程序测试。 写了个server的代码进行

测试。

10个线程同时对一个fd进行write, 看看客户端会收到什么数据。

服务端代码:

#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)

反复执行程序会发现, 客户端收到的数据段,重复数据全部是连续的, 没有一次非连续数据出现, 这已经说明,操作系统在write/send的时候,会对socket的写缓冲区加锁。其实无论是linux还是windows,Socket都是线程安全的。

所以程序不用担心也不需要对套接字进行同步了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值