1024個讀出執行緒,傳送端不控制速度。測試包長2kb, 測試時間983秒時, 單個執行緒的頻寬為0.0068gb/s, 此時的擁塞視窗為17,rtt為45000. 傳送端的cpu佔用率為18%, 接收端的cpu佔用率為34%。接收端的recv-q為0,傳送端的send-q為幾百kb。
傳送端和接收端先建立1024個連線,然後再用pthread_create建立1024個執行緒,傳送端每個執行緒呼叫send()函式傳送資料,接收端每個執行緒呼叫recv()函式接收資料。
在傳送資料的初期,單執行緒的頻寬達到200mb/s,隨著每個執行緒傳送到網路的分組越來越多,網路發生了擁塞,tcp的重傳率明顯提高到2%, 接著擁塞視窗不斷降低,頻寬也降低到乙個很小的值,接著會發生慢啟動的過程,頻寬又逐漸上公升,並維持在每個執行緒6mb/s左右, 總頻寬大約為6gb/s左右。
測試程式:
伺服器端:g++ -lpthread server1bak.c -o sbak
1 #include 2 #include 3客戶端: g++ -lpthread client1_multi_sock.c -o cbak4 #include5 #include 6
7 #include 8 #include 9 #include in.h>
10 #include 11 #include12 #include13 #include
1415
#define ip "192.168.250.146"
16#define port 33333
17#define socknum 1024
18#define packetsize 2048
1920 typedef struct
arg; 23
24pthread_t tid[socknum]; 25
26int senddata(int
sock) 27
39 size_left -=ret; 40
} 4142
return
size_left; 43
} 4445
46int read_cwnd(int
tcp_work_socket) 47
58return0;
59}
6061
62void *senddata(void *arg)63
8990
#if 1
91if(timer > 3600000000)
92 98#endif99}
100}
101return0;
102#endif
103104
}105
106107
108int
main()
109120
121 addr_ser.sin_family =af_inet;
122 addr_ser.sin_port =htons(port);
123 addr_ser.sin_addr.s_addr =inet_addr(ip);
124125
126int sockopt = 1
;127
if (setsockopt(sock, sol_socket, so_reuseport, (char *)&sockopt, sizeof(int)) < 0
)128
132133
if (bind(sock, (struct sockaddr*)&addr_ser, sizeof(struct sockaddr)) < 0
)134
138139
if (listen(sock, 2000) < 0
)140
144145
146for(int i=0; i)
147155 printf("
accept ok!\n");
156}
157158
159#if 1
160161
//static extern pthread_t tid[socknum];
162arg a[socknum];
163for(int i=0; i)
167#endif
168169
#if 1
170for(int i=0; i)
171174
#endif
175176
return0;
177 }
1 #include 2 #include 34 #include5 #include 6 #include 7
8 #include 9 #include 10 #include in.h>
11 #include12 #include
1314
#define ip "192.168.250.146"
15#define port 33333
1617
#define socknum 1024
18#define thread_num 1024
19#define socket_per_thread 1
2021
22 typedef struct
arg; 25
2627
int recvdata(int sock, char *buffer) 28
40else41
44} 45
return
nrecv; 46
} 4748
void *recvdata(void *arg) 49
72#endif73}
74}
75return0;
76}
7778
79int
main() 80
9697 addr_ser.sin_family =af_inet;
98 addr_ser.sin_port =htons(port);
99 addr_ser.sin_addr.s_addr =inet_addr(ip);
100101 addr_cli[i].sin_family =af_inet;
102 addr_cli[i].sin_port = htons(12345+i);
103 addr_cli[i].sin_addr.s_addr =inet_addr(local_ip.c_str());
104105
106107
int sockopt = 1
;108
if (setsockopt(sock[i], sol_socket, so_reuseaddr, (char*)&sockopt, sizeof(sockopt)) == -1
)109
113114
if( bind(sock[i], (struct sockaddr*)&addr_cli[i], sizeof(addr_cli[i]) ) < 0
)115
119 printf("
bind ok!\n");
120121
if(connect(sock[i], (struct sockaddr*)&addr_ser, sizeof(struct sockaddr)) < 0
)122
126 printf("
connect ok!\n");
127128
}129
130131
pthread_t tid[thread_num];
132arg a[thread_num];
133for(int i=0; i)
134139 pthread_create(&tid[i], 0, recvdata, (void *)&a[i]);
140}
141142
for(int i=0; i)
143146
147return0;
148 }
C C 四種退出執行緒的方法
c c 四種退出執行緒的方法 退出執行緒可以有四種方法 1.執行緒函式的return返回 最好這樣 2.呼叫 endthreadex 函式 或 exitthread 函式 最好不要 如果使用這兩種方法退出執行緒,則不會執行執行緒函式的return語句,所以就不會呼叫執行緒函式作用域內申請的類物件的析...
如何寫出執行緒安全的類和函式
什麼是執行緒安全的類和函式,可以被多個執行緒呼叫而不會出現資料的錯亂的類和函式被叫做執行緒安全的類和函式,首先導致執行緒不安全的根本原因是我們函式中或著類中的共享成員變數 如類靜態成員變數,全域性變數 當我們的函式中或者類中有這些變數時他們都是非執行緒安全的,當有多個執行緒呼叫這些函式或者物件時,就...
C C 中退出執行緒的四種解決方法
退出執行緒可以有四種方法 1.執行緒函式的return返回 最好這樣 其中用執行緒函式的return返回,而終止執行緒是最安全的,程函式return返回後,會清理函式內申請的類物件,即呼叫這些物件的析構函式.然後會自動呼叫 endthreadex 函式來清理 beginthreadex 函式申請的資...