日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

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

發(fā)布時(shí)間:2024/10/8 linux 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux的write是线程安全的吗,socket的write/send还是是否是线程安全? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在多線程的網(wǎng)絡(luò)服務(wù)器程序中, 對(duì)同一個(gè)客戶端多線程同時(shí)發(fā)送數(shù)據(jù)是經(jīng)常可能發(fā)生的事情, 也就是有可能會(huì)多

線程的對(duì)一個(gè)fd調(diào)用send/write, 那么這種操作是否需要加鎖?并發(fā)寫套接字是否導(dǎo)致系統(tǒng)緩沖區(qū)數(shù)據(jù)混亂呢? 網(wǎng)上搜

了下,有人說可以寫,有人說不能,linux man page也沒有說明。 看來需要寫程序測(cè)試。 寫了個(gè)server的代碼進(jìn)行

測(cè)試。

10個(gè)線程同時(shí)對(duì)一個(gè)fd進(jìn)行write, 看看客戶端會(huì)收到什么數(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簡(jiǎn)單寫個(gè)測(cè)試程序

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í)行程序會(huì)發(fā)現(xiàn), 客戶端收到的數(shù)據(jù)段,重復(fù)數(shù)據(jù)全部是連續(xù)的, 沒有一次非連續(xù)數(shù)據(jù)出現(xiàn), 這已經(jīng)說明,操作系統(tǒng)在write/send的時(shí)候,會(huì)對(duì)socket的寫緩沖區(qū)加鎖。其實(shí)無論是linux還是windows,Socket都是線程安全的。

所以程序不用擔(dān)心也不需要對(duì)套接字進(jìn)行同步了。

總結(jié)

以上是生活随笔為你收集整理的linux的write是线程安全的吗,socket的write/send还是是否是线程安全?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。