標籤:
在我的裡面已經介紹了linux下面c的進程、線程介面,這裡就不做過多闡述了。
多進程
這裡多進程採用傳統的多進程模型,每當有用戶端發來的串連時建立一個進程來處理串連,一個子進程對應一個串連。
有了上篇單一進程的基礎,此處只做簡單的修改便可以實現。
while(1){ clientfd = Accept(servfd, (struct sockaddr*)&cliaddr, &clientlen); host = Gethostbyaddr((const char*)&cliaddr.sin_addr.s_addr, sizeof(cliaddr.sin_addr.s_addr), AF_INET); printf("server connect to host: %s %s\n",host->h_name, inet_ntoa(cliaddr.sin_addr)); if ((child_pid = Fork()) == 0){ Close(servfd); echo(clientfd); Close(clientfd); } Close(clientfd); }只需要在while裡面添加進程的建立即可,然後在子進程裡先關閉父進程的監聽通訊端。
當然,不要忘了在上面添加Fork錯誤處理的包裹函數(在Fork一節中已講到)。
void error_msg(char *msg){ perror(msg); exit(0);}int Fork(){ pid_t pid; if ( ( pid = fork() ) < 0 ) error_msg("fork failed"); return pid;}
運行結果:
用戶端:
伺服器:
多線程
線程和進程在很多方面是相通的,仿照上面的多進程的傳統模型,不難實現多線程的傳統模型。
依然是在while裡面做簡單的修改即可。
clientfd = (int*)malloc(sizeof(int)); *clientfd = Accept(servfd, (struct sockaddr*)&cliaddr, &clientlen); host = Gethostbyaddr((const char*)&cliaddr.sin_addr.s_addr, sizeof(cliaddr.sin_addr.s_addr), AF_INET); printf("server connect to host: %s %s\n",host->h_name, inet_ntoa(cliaddr.sin_addr)); Pthread_create(&tid, NULL, &thread, clientfd); Close(*clientfd);
使用malloc是為了避免由於多線程訪問了相同的clientfd從而出現無法預估的後果,所有手動分配。
線程函數為
void *thread(void* arg){ int clientfd = *((int*)arg); free(arg); Pthread_detach(pthread_self()); echo(clientfd); close(clientfd); return NULL;}
運行結果:
這段代碼有個問題,clientfd傳入線程之後,arg指標沒有接收到值,指在了一個無法訪問的地方(gdb顯示值為0x00),百思不得其解。
(原理很簡單,遇到的問題先記錄下,如果有人知道錯在哪裡希望能指正出來。。。 環境 ubuntu 64位,編譯器gcc)
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Linux網路編程(3)——多進程、多線程