本文为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);
}
}

UNIX网络编程卷1 server程序设计范式7 预先创建线程,以相互排斥锁上锁方式保护accept的更多相关文章

  1. UNIX网络编程卷1 server程序设计范式8 预先创建线程,由主线程调用accept

    本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.程序启动阶段创建一个线程池之后仅仅让主线程调用 accept 并把客户连接传递给池中某个 ...

  2. UNIX网络编程卷1 server程序设计范式1 并发server,为每一个客户请求fork一个进程

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.传统并发server调用 fork 派生一个子进程来处理每一个客户 2.传统并发serv ...

  3. UNIX网络编程卷1 server编程范式0 迭代server

    本文senlie原版的.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.迭代 TCP server总是在全然处理某个客户的请求后才转向下一个客户. 2.从进程控 ...

  4. [转载] 读《UNIX网络编程 卷1:套接字联网API》

    原文: http://cstdlib.com/tech/2014/10/09/read-unix-network-programming-1/ 文章写的很清楚, 适合初学者 最近看了<UNIX网 ...

  5. UNIX网络编程 卷2:进程间通信

    这篇是计算机类的优质预售推荐>>>><UNIX网络编程 卷2:进程间通信(第2版)> UNIX和网络专家W. Richard Stevens的传世之作 编辑推荐 两 ...

  6. 《UNIX网络编程 卷1》之"学习环境搭建"(CentOS 7)

    <UNIX网络编程 卷1>的源码可以从www.unpbook.com下载得到.解压之后的目录为unpv13e. 详细步骤 编译 进入unpv13e目录,按如下步骤编译: ./configu ...

  7. UNIX网络编程卷1 时间获取程序server TCP 协议相关性

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 最初代码:  这是一个简单的时间获取server程序.它和时间获取程序client一道工作. ...

  8. 《Unix网络编程卷1:套接字联网API》读书笔记

    第一部分:简介和TCP/IP 第1章:简介 第2章:传输层:TCP.UDP和SCTP TCP:传输控制协议,复杂.可靠.面向连接协议 UDP:用户数据报协议,简单.不可靠.无连接协议 SCTP:流控制 ...

  9. UNIX网络编程卷1 - >环境搭建(ubuntu16.04)

      学习unp网络编程,树上的例子均存在#include“unp.h”,故需要对环境进行配置. 1.到资源页下载www.unpbook.com 2.解压并将unpv13e移动到相应的文件夹下 (因为我 ...

随机推荐

  1. 【源代码】LinkedHashMap源代码剖析

    注:下面源代码基于jdk1.7.0_11 之前的两篇文章通过源代码分析了两种常见的Map集合,HashMap和Hashtable.本文将继续介绍还有一种Map集合--LinkedHashMap. 顾名 ...

  2. 嵌入式Linux常见问题

    Linux问题集 1 linux设置环境变量及保存地点 1. 显示环境变量HOME $ echo $HOME /home/terry 2. 设置一个新的环境变量WELCOME $ exportWELC ...

  3. ocx控件避免弹出警告的类--2

    本文与 OCX控件避免弹出安全警告的类 http://www.cnblogs.com/lidabo/archive/2013/03/26/2981852.html 有些类似,只不过增加了几行代码(红色 ...

  4. Android 特殊符号的转码大全

    项目中要在string.xml 中显示特殊符号,如@号冒号等,直接写肯定不行啦..只能考虑使用ASCII码进行显示: @号 @ :号 : 空格   以下为常见的ASCII十进制交换编码: --> ...

  5. Mina2 研究总结

    一.Mina框架. Mina的框架大概是这么个样子: 底层由Java 的NIO 1.0实现 核心架构应该是这样: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZX ...

  6. datarow用linq查询

    List<string> f_guids = (from DataRow dr in dt2.Rows select dr["f_GUID"].ToString()). ...

  7. 【菜鸟看框架】——EF怎样自己主动生成实体

    引言 在上一篇博客中给大家介绍了一些关于EF框架的基本知识.让大家对实体架构算是有了一个入门的认识,当然知识 这一篇博客是不能非常清楚的理解实体架构的内涵的.我们须要在实践中自己去不断的研究和探索当中 ...

  8. WCF 项目应用连载[8] - 绑定、服务、行为 大数据传输与限流 - 下 (ServiceThrottlingAttribute)

    因为ORM的原因,对Attribute编程有一种情节..所以这节的出现,完全是因为在WCF对自定义Attribute的一种应用. WCF 项目应用连载[7] - 绑定.服务.行为 大数据传输与限流 - ...

  9. Android相关

    wifi密码:因为我们安卓系统的手机无线账号数据是储存在一个文件里的,那就是 /data/misc/wifi/wpa_supplicant.conf ,这个是系统文件,权限不够高是无法访问的,而这个文 ...

  10. onkeypress事件.onkeydown事件.onkeyup事件

    onkeypress事件是在按键開始按的时候发生: onkeydown事件是在按键已经按下的时候发生: onkeyup事件是在按键松开(释放)的时候发生.