1. 程式人生 > >多執行緒解決socket併發問題

多執行緒解決socket併發問題

概念

  • 這篇部落格我們利用多執行緒解決伺服器併發問題
  • 程序是資源分配最小的單位,執行緒是CPU排程的最小單位
  • 多程序與多執行緒比較(下圖取自網路,原作者不詳)



對比維度

多程序

多執行緒

總結

資料共享、同步

資料共享複雜,需要用IPC;資料是分開的,同步簡單

因為共享程序資料,資料共享簡單,但也是因為這個原因導致同步複雜

各有優勢

記憶體、CPU

佔用記憶體多,切換複雜,CPU利用率低

佔用記憶體少,切換簡單,CPU利用率高

執行緒佔優

建立銷燬、切換

建立銷燬、切換複雜,速度慢

建立銷燬、切換簡單,速度很快

執行緒佔優

程式設計、除錯

程式設計簡單,除錯簡單

程式設計複雜,除錯複雜

程序佔優

可靠性

程序間不會互相影響

一個執行緒掛掉將導致整個程序掛掉

程序佔優

分散式

適應於多核、多機分散式;如果一臺機器不夠,擴充套件到多臺機器比較簡單

適應於多核分散式

程序佔優

程式碼實現


  • 伺服器端利用多執行緒程式設計
  • 注意編譯的時候加上-lpthread ,否則會出現如下編譯錯誤
undefined reference to `pthread_create’
collect2: ld 返回 1
#include <pthread.h>
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> void *thread_worker(void *arg); int *p; int main(int argc, char **argv) { int socket_fd, connect_fd = -1
; struct sockaddr_in serv_addr; pthread_t tid; socket_fd = socket(AF_INET, SOCK_STREAM, 0); if(socket_fd < 0 ) { printf("create socket failure: %s\n", strerror(errno)); return -1; } printf("socket create fd[%d]\n", socket_fd); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(9998); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(socket_fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ) { printf("create socket failure: %s\n", strerror(errno)); return -2; } printf("socket bind ok\n", socket_fd); listen(socket_fd, 13); printf("listen fd ok\n", socket_fd); while(1) { printf("waiting for client's connection......\n", socket_fd); connect_fd = accept(socket_fd, NULL, NULL); p=&connect_fd; if(connect_fd < 0) { printf("accept new socket failure: %s\n", strerror(errno)); return -2; } printf("accept ok, return connect_fd: [%d]\n", connect_fd); pthread_create (&tid, NULL,thread_worker, (void *)p); } close(socket_fd); } void *thread_worker(void *arg) { char buf[1024]; int cli_fd =*p; memset(buf, 0, sizeof(buf)); while(1){ read(cli_fd, buf, sizeof(buf)); printf("read '%s' from client\n", buf); printf("send data to client:"); fgets(buf,sizeof(buf),stdin); write(cli_fd, buf, strlen(buf)); sleep(1); } close(cli_fd); return NULL; }