博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP并发服务器(六)——创建线程池,每个线程accept,accept使用互斥锁保护——基于UNP代码...
阅读量:4583 次
发布时间:2019-06-09

本文共 2339 字,大约阅读时间需要 7 分钟。

TCP并发服务器(六)——创建线程池,每个线程accept,accept使用互斥锁保护——基于UNP代码

 

1.说明

预创建一个线程池,线程池中各个线程accept。主线程不做什么。

这是Leader/Follower领导者/跟随者模式

 

2.代码

代码基于UNP的库函数

我们没有让线程阻塞于accept, 而是选择了互斥锁保证只有一个线程再接收。

我们没有理由使用文件锁,因为对于进程中的各个线程,总可以使用互斥锁,而且性能更好。

 

在源自BSD的内核中,我们可以不为accept上锁。使得用户CPU时间减少,但是系统CPU时间会增加。

原因是因为多个线程被唤醒引发惊群。总的时间会增加。

由于把每个连接派遣到线程池中某个线程需要互斥,因此内核派遣不如通过线程函数库派遣快

这个版本是当前版本中最快的。

#include "unpthread.h"//线程信息typedef struct {    pthread_t    thread_tid;        //thread ID    long        thread_count;    //connections handled    } Thread;//线程结构数组Thread *tptr;                    //array of Thread structures; calloc'edint listenfd, nthreads;socklen_t addrlen;pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;static void thread_make(int i);static void sig_int(int signo){    void pr_cpu_time(void);    pr_cpu_time();    exit(0);}int main(int argc, char *argv[]){    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: a.out [ 
]
<#threads>"); } nthreads = atoi(argv[argc - 1]); tptr = (Thread*)Calloc(nthreads, sizeof(Thread)); //预创建一定数目线程 for (int i = 0; i < nthreads; ++i) { thread_make(i); } Signal(SIGINT, sig_int); //主线程什么也不做,创建的各个线程accept for (;;) { pause(); } return 0;}static void *thread_main(void *arg){ //第几个线程 int tcnt = (int)arg; DPRINTF("thread %d starting\n", tcnt); void web_child(int); struct sockaddr *cliaddr = (struct sockaddr*)Malloc(addrlen); //accept,然后处理连接 for (;;) { socklen_t clilen = addrlen; DPRINTF("thread %d lock\n", tcnt); //加锁 Pthread_mutex_lock(&mlock); DPRINTF("thread %d start to accept\n", tcnt); int connfd = Accept(listenfd, cliaddr, &clilen); DPRINTF("thread %d accept a connection\n", tcnt); Pthread_mutex_unlock(&mlock); DPRINTF("thread %d unlock\n", tcnt); ++tptr[tcnt].thread_count; DPRINTF("thread %d accept %d connections\n", tcnt, tptr[tcnt].thread_count); web_child(connfd); Close(connfd); } return NULL;}static void thread_make(int i){ Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void*)i); return;}

转载于:https://www.cnblogs.com/hancm/p/3858753.html

你可能感兴趣的文章
Oracle学习第七课-表连接及其应用
查看>>
Python基础篇【第十三篇】:面向对象
查看>>
bzoj 2465 小球
查看>>
String类
查看>>
NoSQL简介
查看>>
java_2018_Day5_变量的格式
查看>>
在C++中调用DLL中的函数
查看>>
leetcode 32. Longest Valid Parentheses
查看>>
OpenSSL创建私有CA
查看>>
CSS3画腾讯QQ图标 无图片和js参考
查看>>
C#使用Emit生成构造函数和属性
查看>>
python pip源配置,pip配置文件存放位置
查看>>
[数据库]关于MAX()函数的一个坑
查看>>
实现前后滚动效果-axure设计实例
查看>>
windows下mysql忘记root密码--吐血测试,都是泪
查看>>
lnmp集成开发环境安装pdo_dblib扩展
查看>>
linux web.py spawn-fcgi web.py 配置
查看>>
lintcode : 空格替换
查看>>
lintcode 中等题:subsets II 带重复元素的子集
查看>>
【原创】Linux基础之测试域名IP端口连通性
查看>>