linux 網路程式設計之伺服器多執行緒限制
本文討論伺服器端多執行緒併發的操作和限制:
基於實驗結果和百度結果:
實驗基礎:伺服器和客戶端,伺服器為每個客戶端連線開闢執行緒,驗證伺服器多執行緒的最大支援數目
實驗環境:ubuntu 12.04
實驗結果: 1、一切系統預設設定的情況下,最多接收了381個連結,也即開啟了381個執行緒。
實驗總結:為得到儘可能多的執行緒,可從下面幾個方面考慮:
一、及時回收執行緒資源
預設情況下,執行緒的資源是在主執行緒結束時才會被回收,線上程結束時資源並不能馬上被釋放;
我們可以呼叫pthread_detach()函式,在主執行緒或是子執行緒將子執行緒與主執行緒分離,這樣一旦子執行緒結束就會立即釋放子執行緒佔用的資源,這些資源可供新的連線使用
二、棧大小對執行緒數目的限制
ubuntu中預設的棧空間是8MB,而每個程序的虛擬記憶體空間是3GB,那麼正常情況下可以開啟382個執行緒,這與上述實驗結果吻合
我們可以更改棧大小,進而建立更多的執行緒。
更改棧大小的兩個方法:1、ulimit -s 1024(改為1M) 2、使用pthread_attr_t執行緒屬性
三、系統設定的最大執行緒數目
linux下對執行緒的數目有兩個地方的設定:
1、linux系統中所有程序所能開啟的總的執行緒數:
cat /proc/sys/kernel/threads-max
15783
2、linux 系統中單個程序的最大執行緒數有其最大的限制 PTHREAD_THREADS_MAX
這個限制可以在 /usr/include/bits/local_lim.h 中檢視;ubuntu中位於/usr/include/i386-linux-gnu/bits/local_lim.h
/* The number of threads per process. */
#define _POSIX_THREAD_THREADS_MAX 64
/* We have no predefined limit on the number of threads. */
#undef PTHREAD_THREADS_MAX
/* Minimum size for a thread. We are free to choose a reasonable value. */
#define PTHREAD_STACK_MIN 16384
可以看出,posix標準中是64個執行緒,但在ubuntu中並沒有預先定義PTHREAD_THREADS_MAX
對於 linux這個值一般是 1024,對於 nptl 則沒有硬性的限制,僅僅受限於系統的資源,這個系統的資源主要就是執行緒的 stack 所佔用的記憶體,用 ulimit -s 可以檢視預設的執行緒棧大小,ubuntu下這個值是8M
四、檔案描述的限制
在socket連線中,每個連結需要一個讀寫描述符(實質就是檔案描述符);系統預設下,每個程序所能使用的最大描述符數目是1024;
這也是為什麼將棧大小改為1M後,最大執行緒資料不能超過1020的原因所在。
在根使用者下將檔案描述符修改為5000:ulimit -n 5000;然後切換到普通使用者,重新執行server,此時最多可以達到3000+,這也是符合理論值的,3G的虛擬程序記憶體,1M的棧空間,理論值可以達到3050個執行緒。
具體的修改方法:
五、埠數目限制
伺服器連線中需要為每個連線分配埠號,linux中埠的分配有一個範圍,超出該範圍將不能建立連線,該範圍大概有近三萬的埠可供使用
貼上伺服器端程式碼
void *thread_handle(void *fd);
void sigint_handle(int sig);
static int server_fd = -1;
int get_thread_stacksize_for_attr(pthread_attr_t * p_pattr)
{
int status = 0;
size_t size = 0;
//printf("default size:%d\n", size);
status = pthread_attr_getstacksize(p_pattr, &size);
if(0 != status)
{
printf("pthread_attr_getstacksize err [%d]\n",status);
return -1;
}
printf("current thread stack size:%d\n", size);
return 0;
}
int set_thread_stacksize(pthread_attr_t * p_pthread_attr_t,size_t size)
{
//pthread_attr_t pattr;
int status = 0;
//printf("default size:%d\n", size);
status = pthread_attr_setstacksize(p_pthread_attr_t, size);
if(0 != status)
{
printf("pthread_attr_getstacksize err [%d]\n",status);
return -1;
}
printf("set thread stack size:%d\n", size);
return 0;
}
int main(int argc,char *argv[])
{
int *client_fd;
struct sockaddr_in server_addr = {0};
struct sockaddr_in client_addr = {0};
socklen_t client_address_len = 0;
int ret = -1;
char client_address_buf[20] = {0};
pthread_t thread_id = -1;
pthread_attr_t pattr;
pthread_attr_init(&pattr);
set_thread_stacksize(&pattr,1024*1024);
get_thread_stacksize_for_attr(&pattr);
if(SIG_ERR == signal(SIGINT,sigint_handle))
{
perror("signal");
exit(-1);
}
server_fd = socket(AF_INET,SOCK_STREAM,0);
if(server_fd < 0)
{
perror("socket");
exit(-1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IPADDRESS);
ret = bind(server_fd,(const struct sockaddr *)&server_addr,sizeof(server_addr));
if(ret < 0)
{
perror("bind");
exit(-1);
}
ret = listen(server_fd,BACKLOG);
if(ret < 0)
{
perror("listen");
exit(-1);
}
printf("listening\n");
while(1)
{
client_fd = (int *)malloc(sizeof(int));
*client_fd = accept(server_fd,(struct sockaddr *)&client_addr,(socklen_t *)&client_address_len);
if(client_fd < 0)
{
perror("accept");
exit(-1);
}
inet_ntop(AF_INET,(const void *)&client_addr.sin_addr,client_address_buf,sizeof(client_address_buf));
printf("client IP:%s port:%hu client_fd:%d\n",client_address_buf,ntohs(client_addr.sin_port),*client_fd);
ret = pthread_create(&thread_id,&pattr,thread_handle,(void *)client_fd);
if(ret)
{
perror("pthread_create");
exit(-1);
}
//pthread_detach(thread_id);
//get_thread_stacksize_for_attr(&pattr);
}
return 0;
}
void *thread_handle(void *fd)
{
char recv_buf[30] = {0};
int ret = -1;
int *client_fd = (int *)fd;
//pthread_detach(pthread_self());
while(1)
{
ret = recv(*client_fd,(void *)recv_buf,sizeof(recv_buf),0);
if(-1 == ret)
{
perror("recv");
exit(-1);
}
else if(0 == ret)
{
printf("client disconnect,client_fd:%d\n",*client_fd);
if(close(*client_fd))
{
perror("close");
exit(-1);
}
free(client_fd);
pthread_exit(0);
}
printf("client_fd:%d bytes:%d %s\n",*client_fd,ret,recv_buf);
memset(recv_buf,0,sizeof(recv_buf));
}
}
void sigint_handle(int sig)
{
if(SIGINT != sig)return;
printf("\nserver termated\n");
close(server_fd);
exit(1);
}
下面附上實驗總結和百度網文,很難整理,直接貼上:
實驗目的:伺服器程序所支援的最大執行緒(考慮4點:棧大小、是否及時回收執行緒資源、系統預設設定的執行緒數、系統預設設定的檔案描述符數量)
實驗過程:client.c連線伺服器成功後,每隔一秒傳送一次資料;server.c為每一個連線建立執行緒,接收資料並列印。
試驗一:更改棧空間
1、server處於監聽狀態是2248K,一旦接收一個連結變為10444K,意味著一個執行緒大概8MB;client執行過程則是2004K
2、將執行緒堆疊的預設值改為1M
server處於監聽狀態是2252K,一旦接收一個連線後變為3280K,增加了1028K,意味著一個執行緒大概為1M;增加第二個執行緒增加仍為1028K;client仍然為2004
3、當開啟二十個連線,也即在server端開啟二十個執行緒,記憶體增加為20*1028
top - 18:10:44 up 8:55, 4 users, load average: 0.04, 0.04, 0.05
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.7%us, 0.7%sy, 0.0%ni, 97.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1024764k total, 628068k used, 396696k free, 136756k buffers
top - 18:12:05 up 8:56, 4 users, load average: 0.01, 0.03, 0.05
Tasks: 22 total, 0 running, 22 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.0%us, 1.0%sy, 0.0%ni, 97.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1024764k total, 630024k used, 394740k free, 136756k buffers
Swap: 1046524k total, 0k used, 1046524k free, 330296k cached
這種情況下,每個執行緒只有97K的記憶體佔用(猜測,這可能是實際佔用的儲存空間,真正用到的空間)
free 628060 629876 每個程序只用了90K
實驗二:不回收資源,不改變棧空間的情況下,server支援的最大執行緒數目
1、超過三百個連結(大概在318之後) 會掛掉;第二次試驗在360掛掉;第三次380(第四次,第五次)
2、即使關閉一部分連線,但其資源沒有被立即釋放
3、用測試程式測試,可以開啟的最大執行緒數是382
ps -aux | grep "server" (VSZ:該程序所佔用的虛擬記憶體量(KB);RSS:該程序所佔用的固定的記憶體量(KB);)
rss 實際開銷的實體記憶體,這些記憶體都是該程序現在正在使用的實體記憶體。
vsz 虛擬記憶體大小,也就是說,程式目前沒有使用,但是可能會分配的記憶體大小。
vsz:
執行200個連結(200個執行緒),記憶體佔用1641452((1641452-2252)/200 =8196=8.0039MK)
執行300個連結(300個執行緒),記憶體佔用2461052((2461052-2252)/300 =8196=8.0039MK)
實際的記憶體空間根本沒有這麼大(虛擬機器實際上只有1G的空間),猜測1,虛擬記憶體;猜測2,每個執行緒的實際佔用記憶體只有100K左右。
rss:
user 3977 0.0 0.0 2252 316 pts/0 S+ 10:44 0:00 ./server (無連線)
user 3977 1.2 0.1 2461052 1632 pts/0 Sl+ 10:44 0:00 ./server (300連線)
(1632-316)/300=4.38K
使用top -H -p命令
top - 10:27:02 up 42 min, 3 users, load average: 0.11, 0.12, 0.11
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.7%us, 0.7%sy, 0.0%ni, 96.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1024764k total, 461624k used, 563140k free, 129184k buffers
Swap: 1046524k total, 0k used, 1046524k free, 189616k cached
top - 10:30:35 up 46 min, 3 users, load average: 0.18, 0.13, 0.12
Tasks: 301 total, 0 running, 301 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.7%us, 4.7%sy, 0.0%ni, 94.6%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1024764k total, 468584k used, 556180k free, 129184k buffers
Swap: 1046524k total, 0k used, 1046524k free, 189616k cached
(468584-461624)/300 = 23.2K (使用的實體記憶體的總量)
這個值和理論完全相符,因為 32 位 linux 下的程序使用者空間是 3G 的大小,也就是 3072M,用 3072M 除以 8M 得 384,但是實際上程式碼段和資料段等還要佔用一些空間,這個值應該向下取整到 383,再減去主執行緒,得到 382。
那為什麼 linuxthreads 上還要少一個執行緒呢?這可太對了,因為 linuxthreads 還需要一個管理執行緒
為了突破記憶體的限制,可以有兩種方法
1) 用 ulimit -s 1024 減小預設的棧大小
2) 呼叫 pthread_create 的時候用 pthread_attr_getstacksize 設定一個較小的棧大小
要注意的是,即使這樣的也無法突破 1024 個執行緒的硬限制,除非重新編譯 C 庫
實驗三:回收資源(pthread_detach),當然了,同時執行的連線還是不能達到400;關閉的連線資源被馬上釋放,可以供新的連線所使用(當執行三百連線時,先關閉一百個連線,再開啟一百個連線,是可以的)
結論:pthread_detach可以線上程結束後,馬上釋放資源!
實驗三:不回收資源,但減少執行緒棧空間:將執行緒屬性中的棧空間改為1MK
user 4643 0.0 0.0 2252 312 pts/0 S+ 10:55 0:00 ./server
user 4643 1.2 0.1 310652 1628 pts/0 Sl+ 10:55 0:01 ./server
可以看出,vsz大大減少 (310652-2252)/300 = 1028K 而rss則幾乎沒有發生變化!
開啟1000個連結(1000個執行緒)
user 5283 0.9 0.4 1030384 4532 pts/0 Sl+ 11:01 0:00 ./server
(4532-316)/1000=4.22K
(1030384-2252)/1000=1028K
此時的最大連線數1018(小於1020個),但測試程式跑起來的時候是3054個執行緒,這裡的原因在於檔案描述符,ubuntu中每個程序的檔案描述符最大為1024個,ubuntu中並沒有對程序的最大執行緒數目做出限制。
[[email protected] test]# ulimit -s 1024
[[email protected] test]# ./test
pthread_create() failure
Max pthread num is 3054
1、檢視最大執行緒數(系統所有程序所能開啟的總的執行緒數):
cat /proc/sys/kernel/threads-max
15783
2、Ulimit命令
設定限制 可以把命令加到profile檔案裡,也可以在/etc/security/limits.conf檔案中定義
限制。
命令引數
-a 顯示所有限制
-c core檔案大小的上限
-d 程序資料段大小的上限
-f shell所能建立的檔案大小的上限
-m 駐留記憶體大小的上限
-s 堆疊大小的上限
-t 每秒可佔用的CPU時間上限
-p 管道大小
-n 開啟檔案數的上限
-u 程序數的上限
-v 虛擬記憶體的上限
除可用Ulimit命令設定外,也可以在/etc/security/limits.conf檔案中定義限制。
domino type item value
domino是以符號@開頭的使用者名稱或組名,*表示所有使用者,type設定為hard or soft。item指
定想限制的資源。如cpu,core nproc or maxlogins。value是相應的限制值。
系統限制預設值(ubuntu)
[email protected]:~/socket$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7891
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7891
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
[email protected]:~/socket$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 12.04.2 LTS
Release: 12.04
Codename: precise
3、linux 系統中單個程序的最大執行緒數有其最大的限制 PTHREAD_THREADS_MAX
這個限制可以在 /usr/include/bits/local_lim.h 中檢視
ubuntu中位於/usr/include/i386-linux-gnu/bits/local_lim.h
/* The number of threads per process. */
#define _POSIX_THREAD_THREADS_MAX 64
/* We have no predefined limit on the number of threads. */
#undef PTHREAD_THREADS_MAX
/* Minimum size for a thread. We are free to choose a reasonable value. */
#define PTHREAD_STACK_MIN 16384
對 linuxthreads 這個值一般是 1024,對於 nptl 則沒有硬性的限制,僅僅受限於系統的資源
可以看出,posix標準中是64個執行緒,但在ubuntu中並沒有預先定義PTHREAD_THREADS_MAX,這應該會受限於系統資源
這個系統的資源主要就是執行緒的 stack 所佔用的記憶體,用 ulimit -s 可以檢視預設的執行緒棧大小,ubuntu下這個值是8M
一、2.4核心與2.6核心的主要區別
在2.4核心的典型系統上(AS3/RH9),執行緒是用輕量程序實現的,每個執行緒要佔用一個程序ID,在伺服器程式上,如果遇到高點選率訪問,會造成程序表溢位,系統為了維護溢位的程序表,會有間歇的暫停服務現象,而2.6核心就不會發生由於大量執行緒的建立和銷燬導致程序表溢位的問題
二、執行緒結束必須釋放執行緒堆疊
就是說,執行緒函式必須呼叫pthread_exit()結束,否則直到主程序函式退出才釋放,特別是2.6核心環境,執行緒建立速度飛快,一不小心立刻記憶體被吃光,這一點反倒是2.4核心環境好,因為2.4核心建立的是程序,而且執行緒建立速度比2.6核心慢幾個數量級。特別提醒,在64位CPU,2.6核心建立執行緒的速度更加瘋狂,要是太快的話,加上usleep ()暫停一點點時間比較好
三、不要編需要鎖的執行緒應用
只有那些不需要互斥量的程式才能最大限度的利用執行緒程式設計帶來的好處,否則只會更慢,2.6核心是搶佔式核心,執行緒間共享衝突發生的機率遠比2.4核心環境高,尤其要注意執行緒安全,否則就算是單CPU也會發生莫名其妙的記憶體不同步(CPU的快取記憶體和主存內容不一致),Intel的新CPU為了效能使用NUMA架構,線上程程式設計中一定要注意揚長避短。
四、單程序伺服器最大併發執行緒數與記憶體
很有趣,在預設的ulimit引數下,不修改核心標頭檔案
AS3 512M記憶體最多1000併發持續連線
CentOS4.3 512M記憶體最多300併發持續連線
似乎是CentOS不如AS3,這裡主要原因是ulimit的配置造成,兩個系統預設的配置差距很大,要想單程序維持更多執行緒接收併發連線,就要儘量縮小 ulimit -s的引數,插更多的記憶體條,單程序伺服器上2000併發一點都不難,POSIX預設的限制是每程序64執行緒,但NTPL並非純正POSIX,不必理會這個限制,2.6核心下真正的限制是記憶體條的插槽數目(也許還有買記憶體的錢數)
最近幾天的程式設計中,注意到在32位x86平臺上2.6核心單程序建立最大執行緒數=VIRT上限/stack,與總記憶體數關係不大,32位x86系統預設的VIRT上限是3G(程序執行的虛擬地址空間,32位OS下是0-1G的OS和1-4的程序空間),預設 stack大小是10240K,因此單程序建立執行緒預設上限也就300(3072M / 10240K),用ulimit -s 修改stack到1024K則使上限升到大約3050。我手頭沒有64位系統,不知道2.6核心在64位上單程序建立執行緒上限(實際上是本人懶得在同事的機器上裝fc4_x86_64)。
前些天買了一套廉價的64位x86系統(64位賽楊+雜牌915主機板),安裝了CentOS4.3的x86_64版本,跑了一遍下面的小程式,得到的結果是:在ulimit -s 4096的情況下,單程序最大執行緒數在16000多一點,用top看
VIRT 的上限是64G,也就是36位, cat /proc/cpuinfo的結果是:address sizes : 36 bits physical, 48 bits virtual, 和我想象的標準64位系統不同, 我一直以為64位系統的記憶體空間也是64位的
附註1:
單位裡某BSD FANS用AMD64筆記本跑小程式測試執行緒建立速度(執行緒建立後立即phread_detach()然後緊跟著pthread_exit(),共計 100萬個執行緒),同樣原始碼OpenBSD竟然比FreeBSD快了3倍,什麼時候OpenBSD也變得瘋狂起來了?
附註2:
測試單程序建立執行緒上限C原始碼(test.c):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void * thread_null(void);
int main(int argc, char *argv[])
{
unsigned int i;
int rc;
pthread_t pool_id[65536]; //執行緒ID
sleep(1);
//建立執行緒
for(i = 0; i < 65536; i++) {
rc = pthread_create(pool_id + i, 0, (void *)thread_null, NULL);
if (0 != rc) {
fprintf(stderr, "pthread_create() failure\r\nMax pthread num is %d\r\n", i);
exit(-1);
}
}
fprintf(stdout, "Max pthread num is 65536\r\nYour system is power_full\r\n");
exit(0);
}
void * thread_null(void)
{
pthread_detach(pthread_self());
sleep(60);
pthread_exit(NULL);
}
編譯:[[email protected] test]# gcc test.c -o test -lpthread
[[email protected] test]# ulimit -s 10240
[[email protected] test]# ./test
pthread_create() failure
Max pthread num is 305
[[email protected] test]# ulimit -s 1024
[[email protected] test]# ./test
pthread_create() failure
Max pthread num is 3054
以上結果在 CentOS release 5.2 (32Bit)系統上測試得到
相關推薦
linux 網路程式設計之伺服器多執行緒限制
本文討論伺服器端多執行緒併發的操作和限制: 基於實驗結果和百度結果: 實驗基礎:伺服器和客戶端,伺服器為每個客戶端連線開闢執行緒,驗證伺服器多執行緒的最大支援數目 實驗環境:ubuntu 12.04 實驗結果: 1、一切系統預設設定的情況下,最多接收了381個連結,也即
linux網路程式設計之用多執行緒實現客戶端到服務端的通訊(基於udp)
1、開啟一個執行緒接受資料,主執行緒傳送資料的程式碼 #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #includ
linux網路程式設計之伺服器
基於tcp協議的網路程式 1.所用函式: socket函式 socket()開啟一個網路埠,如果成功,就像open()一樣返回一個檔案描述符,應用程式可以像讀寫檔案一樣用read/write在網路上首發資料,如果調用出錯返回-1 bind函式:
Python併發程式設計之建立多執行緒的幾種方法
今天的內容會比較基礎,主要是為了讓新手也能無障礙地閱讀,所以還是要再鞏固下基礎。學完了基礎,你們也就能很順暢地跟著我的思路理解以後的文章。本文目錄學會使用函式建立多執行緒學會使用類建立多執行緒多執行緒:必學函式講解經過總結,Python建立多執行緒主要有如下兩種方法:函式類接
嵌入式Linux網路程式設計,TCP多併發伺服器,TCP多執行緒併發伺服器,TCP多程序併發伺服器
文章目錄 1,TCP多執行緒併發伺服器 1.1,標頭檔案net.h 1.2,客戶端client.c 1.3,伺服器端server.c 2,TCP多程序併發伺服器 2.1,標頭檔案net.h 2.2,客
linux網路程式設計之多程序併發伺服器
1)使用多程序併發伺服器考慮的因素: (1)父程序描述最大檔案描述符的個數(父程序需要關閉accept返回的新檔案描述符) (2)系統內可建立程序的個數(與記憶體大小相關) (3)程序建立過多是否降低整體服務效能 2)多程序建立併發
javaSE (四十)網路程式設計(TCP傳輸、伺服器多執行緒、網路程式設計練習:反轉字串、上傳檔案)
1、TCP傳輸: 1.客戶端 建立Socket連結服務端(指定ip地址,埠號),通過ip地址找到對應的伺服器 呼叫Socket的getInputStream和getOutputStream方法獲取和伺服器端相連的IO流 2.伺服器端 建立Se
Linux程式設計學習筆記----多執行緒程式設計執行緒同步機制之互斥量(鎖)與讀寫鎖
互斥鎖通訊機制 基本原理 互斥鎖以排他方式防止共享資料被併發訪問,互斥鎖是一個二元變數,狀態為開(0)和關(1),將某個共享資源與某個互斥鎖邏輯上繫結之後,對該資源的訪問操作如下: (1)在訪問該資源之前需要首先申請互斥鎖,如果鎖處於開狀態,則申請得到鎖並立即上鎖(關),防
Linux程式設計學習筆記----多執行緒程式設計之執行緒同步條件變數
轉載請註明出處:http://blog.csdn.net/suool/article/details/38582521. 基本概念與原理 互斥鎖能夠解決資源的互斥訪問,但是在某些情況下,互斥並不能解決問題,比如兩個執行緒需 要互斥的處理各自的操作,但是一個執行緒的操作僅僅存
linux網路程式設計之posix 執行緒(四):posix 條件變數與互斥鎖 示例生產者--消費者問題
#include <unistd.h>#include <sys/types.h>#include <pthread.h>#include <semaphore.h>#include <stdlib.h>#include <stdio.h>
Linux網路程式設計---I/O多路複用之select
1.I/O多路複用(IO multiplexing) 我們之前講了I/O多路複用和其他I/O的區別,在這裡,我們再具體討論下I/O多路複用是怎麼工作? I/O 多路複用技術就是為了解決程序或執行緒阻塞到某個 I/O 系統呼叫而出現的技術,使程序不阻塞於某個特定的 I/O 系統呼叫。
Linux網路程式設計之高階併發伺服器(轉)
1. 介紹 在上一節,我們介紹了Linux簡單的併發伺服器,通過在伺服器端建立多個子程序,來接收客戶端的請求,實現併發處理,但這種方式明顯有缺陷,伺服器並不知道客戶端請求的數量,所以事先建立的程序數不好確定。所以,這裡介紹三種高階併發伺服器模式。第一種是伺服器端統一
Linux網路程式設計 -- poll實現多路IO轉接伺服器
server.c #include <poll.h> #include <stdio.h> #include <errno.h> #include <ctype.h> #include <stdlib.h&
Linux網路程式設計 -- select實現多路IO轉接伺服器
server.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arp
linux伺服器多執行緒還是多程序的選擇及區別
轉自http://blog.csdn.net/lishenglong666/article/details/8557215 魚還是熊掌:淺談多程序多執行緒的選擇 關於多程序和多執行緒,教科書上最經典的一句話是“程序是資源分配的最小單位,執行緒是CPU排程的最小單位”,這
Linux網路程式設計之高階併發伺服器
在上一節,我們介紹了Linux簡單的併發伺服器,通過在伺服器端建立多個子程序,來接收客戶端的請求,實現併發處理,但這種方式明顯有缺陷,伺服器並不知道客戶端請求的數量,所以事先建立的程序數不好確定。所以,這裡介紹三種高階併發伺服器模式。第一種是伺服器端統一accept,接收
Java 多執行緒程式設計之“兩個執行緒實現一個執行緒列印奇數,另一個執行緒列印偶數”
題目:t從0到N,一個執行緒列印奇數,一個執行緒列印偶數,按順序打印出來。 最終列印結果:0,1,2,3,4,...,N; 思路:兩個執行緒間的通訊採用等待,喚醒方法——列印奇偶數由flag控制,當flag為真時列印偶數; 列
linux網路程式設計之-----多播(組播)程式設計
linux網路程式設計之—–多播(組播)程式設計 轉載:https://blog.csdn.net/jmq_0000/article/details/7095727 什麼是多播 ? 單播用於兩個主機之間的端對端通訊,廣播用於一個主
android 之使用多執行緒中的AsyncTask實現下載網路圖片資源
前臺顯示:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:
Linux網路程式設計之I/O複用迴圈伺服器
原文:http://blog.csdn.net/chenjin_zhong/article/details/7270166 1.介紹 在前幾節,我們介紹了迴圈伺服器,併發伺服器. 簡單的迴圈伺服器每次只能處理一個請求,即處理的請求是序列的。而併發伺服器可以通過建立多