多线程编程
处理多client的连接,如果使用线程池模型的话的话,可以让多个线程阻塞在accept上,也可以让多个线程阻塞在read上。相对来讲,阻塞在accept上的写法相对简单
1 阻塞在accept上,让主线程join
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <arpa/inet.h> 5 #include <pthread.h> 6 #include <semaphore.h> 7 #include <errno.h> 8 9 void * acceptClient(void * arg){ 10 //pthread_detach(pthread_self()); 11 struct sockaddr_in client; 12 socklen_t client_len; 13 int listen_fd = *(int *)arg; 14 printf("listen_fd:%d\n", listen_fd); 15 while(1){ 16 printf("Begin accept\n"); 17 int client_fd = accept(listen_fd, (struct sockaddr*)&client, &client_len); 18 char buf[1024]; 19 memset(buf,'\0', sizeof(buf)); 20 while(1){ 21 printf("Had accept [%ld], Begin Read:\n", pthread_self()); 22 int ret = read(client_fd, buf, sizeof(buf)); 23 if(ret > 0){ 24 printf("read ret:%d\n",ret); 25 }else{ 26 printf("Read:%s", strerror(errno)); 27 close(client_fd); 28 } 29 } 30 } 31 } 32 33 int main(){ 34 struct sockaddr_in server; 35 bzero(&server, sizeof(server)); 36 server.sin_family = AF_INET; 37 server.sin_addr.s_addr = htonl(INADDR_ANY); 38 server.sin_port = htons(8888); 39 40 int listen_fd = socket(AF_INET, SOCK_STREAM, 0); 41 bind(listen_fd, (struct sockaddr *)&server, sizeof(server)); 42 listen(listen_fd,128); 43 44 pthread_t clientThread[2]; 45 int client_fd = 0; 46 for(int i = 0; i<2; i++){ 47 pthread_create(&clientThread[i], NULL, acceptClient, (void *)&listen_fd); 48 } 49 for(int i = 0; i<2; i++){ 50 pthread_join(clientThread[i], NULL); 51 } 52 return 0; 53 }
2 子线程阻塞在信号量上,主线阻塞在accept。每次产生一个clientfd, 就sem_post唤醒一个线程处理一下
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <arpa/inet.h> 5 #include <pthread.h> 6 #include <semaphore.h> 7 8 sem_t sem_client; 9 void * acceptClient(void * arg){ 10 pthread_detach(pthread_self()); 11 sem_wait(&sem_client); 12 char buf[1024]; 13 memset(buf,'\0', sizeof(buf)); 14 int client_fd = *(int *)arg; 15 while(1){ 16 printf("ThreadId:%ld, client_fd:%d, Begin read:\n", pthread_self(), client_fd); 17 int ret = read(client_fd, buf, sizeof(buf)); 18 printf("read ret:%d\n",ret); 19 } 20 close(client_fd); 21 } 22 23 int main(){ 24 struct sockaddr_in server; 25 bzero(&server, sizeof(server)); 26 server.sin_family = AF_INET; 27 server.sin_addr.s_addr = htonl(INADDR_ANY); 28 server.sin_port = htons(8888); 29 30 int listen_fd = socket(AF_INET, SOCK_STREAM, 0); 31 bind(listen_fd, (struct sockaddr *)&server, sizeof(server)); 32 listen(listen_fd,128); 33 34 pthread_t clientThread[2]; 35 int client_fd = 0; 36 for(int i = 0; i<2; i++){ 37 pthread_create(&clientThread[i], NULL, acceptClient, (void *)&client_fd); 38 } 39 struct sockaddr_in client; 40 socklen_t client_len; 41 while(1){ 42 client_fd = accept(listen_fd, (struct sockaddr*)&client, &client_len); 43 printf("accept clientfd:%d\n", client_fd); 44 sem_post(&sem_client); 45 } 46 return 0; 47 }

浙公网安备 33010602011771号