zoukankan      html  css  js  c++  java
  • UNIX网络编程卷1 server程序设计范式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 ", 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 ", (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); } }



  • 相关阅读:
    帝国cms 同个IP可提交一次
    帝国cms 图片相对路径绝对路径设置问题+帝国cms 手机端调用图片问题
    帝国CMS 手机版制作+帝国PC跳转到手机+重新定向
    帝国cms 相关问题
    简洁 清晰弹出层讲解制作(图片点击放大)
    webstorm 2016最新版破解+汉化
    ajax点击不断加载数据列表
    js中substr,substring,indexOf,lastIndexOf,split的用法
    Parallax.js|强大的javascript视觉差特效引擎
    一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5066341.html
Copyright © 2011-2022 走看看