UNIX网络编程卷1 服务器程序设计范式7 预先创建线程,以互斥锁上锁方式保护accept
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
1.预先创建一个线程池,并让每个线程各自调用 accept
2.用互斥锁取代让每个线程都阻塞在 accept 调用之中的做法//用于维护关于每个线程基于信息的 Thread 结构 typedef struct { pthread_t thread_tid; /* 线程 ID */ long thread_count; /* 处理的连接数 */ } Thread; Thread *tptr; /* Thread 结构指针,指向一个用 calloc 产生的 Thread结构数组 */ //全局变量,包括监听套接字和一个需收所有线程共享的互斥锁变量 int listenfd, nthreads; socklen_t addrlen; pthread_mutex_t mlock; /* include serv07 */ #include "unpthread.h" #include "pthread07.h" pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER; int main(int argc, char **argv) { int i; void sig_int(int), thread_make(int); //1.创建监听套接字 if (argc == 3) listenfd = Tcp_listen(NULL, argv[1], &addrlen); else if (argc == 4) listenfd = Tcp_listen(argv[1], argv[2], &addrlen); else err_quit("usage: serv07 [ <host> ] <port#> <#threads>"); //2.增设一个命令行参数供用户指定预先派生的线程数 nthreads = atoi(argv[argc-1]); tptr = Calloc(nthreads, sizeof(Thread)); //3.调用 thread_make 创建各个线程 for (i = 0; i < nthreads; i++) thread_make(i); /* 只有父线程才返回 */ //4.设置中断信号 SIGINT 的处理函数 Signal(SIGINT, sig_int); //5.所有事情都由子线程做,主线程阻塞在 pause() for ( ; ; ) pause(); /* everything done by threads */ } /* end serv07 */ //中断信号 SIGINT 处理函数 void sig_int(int signo) { int i; void pr_cpu_time(void); //调用 pr_cpu_time 统计资源利用统计 //在预先派生子进程的代码中还要先给每个子进程发送 SIGTERM 信号终止它们再统计。 //这里由于是线程,而子线程与主线程是在同一个地址空间的,当主线程终止时,子线程也会终止。 pr_cpu_time(); for (i = 0; i < nthreads; i++) printf("thread %d, %ld connections\n", i, tptr[i].thread_count); exit(0); } void thread_make(int i) { void *thread_main(void *); //创建线程并使之执行 thread_main 函数,该函数的唯一参数是本线程在 Thread 结构数组中的下标 Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void *) i); return; /* main thread returns */ } void * thread_main(void *arg) { int connfd; void web_child(int); socklen_t clilen; struct sockaddr *cliaddr; cliaddr = Malloc(addrlen); printf("thread %d starting\n", (int) arg); for ( ; ; ) { clilen = addrlen; //在调用 accept 前后调用 pthread_mutex_lock 和 pthread_mutex_unlock 加以保护 Pthread_mutex_lock(&mlock); connfd = Accept(listenfd, cliaddr, &clilen); Pthread_mutex_unlock(&mlock); tptr[(int) arg].thread_count++; web_child(connfd); /* process request */ Close(connfd); } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。