免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2180 | 回复: 4
打印 上一主题 下一主题

[C++] 网络编程线程池问题 [复制链接]

论坛徽章:
1
2015亚冠之浦和红钻
日期:2015-05-26 14:37:09
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-06-28 15:26 |只看该作者 |倒序浏览
[code]/* include serv08 */
#include "unpthread.h"
#include "pthread08.h"

static int nthreads;
pthread_mutex_t clifd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t clifd_cond = PTHREAD_COND_INITIALIZER;

int
main(int argc, char **argv)
{
    int i, listenfd, connfd;
    void sig_int(int), thread_make(int);
    socklen_t addrlen, clilen;
    struct sockaddr *cliaddr;

    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: serv08 [ ] <#threads>");
    cliaddr = Malloc(addrlen);

    nthreads = atoi(argv[argc-1]);

    tptr = Calloc(nthreads, sizeof(Thread));

    iget = iput = 0;

        /* 4create all the threads */
    for (i = 0; i < nthreads; i++)
        thread_make(i); /* only main thread returns */

    Signal(SIGINT, sig_int);

    for ( ; ; ) {
        clilen = addrlen;
        connfd = Accept(listenfd, cliaddr, &clilen);

        Pthread_mutex_lock(&clifd_mutex);
        clifd[iput] = connfd;
        if (++iput == MAXNCLI)
            iput = 0;
        if (iput == iget)
            err_quit("iput = iget = %d", iput);
        Pthread_cond_signal(&clifd_cond);
        Pthread_mutex_unlock(&clifd_mutex);
    }
}






最近看unp27章中的服务器模型部分,27.12节是并发服务器程序,主线程统一accept
也就是主线程accept,worker线程工作那么模式。作者处理消费者和生产者问题的时候,使用了条件变量和互斥量达到同步。但是我觉得有些问题
作者在考虑循环队列的问题上,是采用如此的策略,在生产者函数中,如果iput==iget,必然是数组缓冲区满,作者直接采用的是、
if (iput == iget)
             err_quit("iput = iget = %d", iput);

也就是说如果生产者的速度,大于消费者的话,我们的主线程只能结束。。这个是不是有待商榷??对应的情况就是,如果多个客户连接连续产生,工作子线程来不及处理的时候,我们的主线程就自己err_quit了。。
有没有更好的办法?(在只采用一个条件变量的条件下)









论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
2 [报告]
发表于 2015-06-28 19:44 |只看该作者
本帖最后由 yulihua49 于 2015-06-28 19:53 编辑
kkshaq 发表于 2015-06-28 15:26
[code]/* include serv08 */
#include "unpthread.h"
#include "pthread08.h"

根本不能这么玩。
纯粹是个学生作业,没有实用价值。

主线程接受连接,然后丢给epoll。线程池在epoll_wait。
接受的连接数可大大超过线程数。他们在epoll排队。

论坛徽章:
1
2015亚冠之浦和红钻
日期:2015-05-26 14:37:09
3 [报告]
发表于 2015-06-28 21:20 |只看该作者
yulihua49 发表于 2015-06-28 19:44
根本不能这么玩。
纯粹是个学生作业,没有实用价值。

线程池这个模型还是可以探讨一下啊

消费者和生产者之间同步的问题。。为什么作者不使用真正的共享缓冲区同步呢。让程序可以一直运行下去。。不然像作者这样,共享缓冲区满了,主线程就得退出啊。
不知道是不是我错了,你觉得呢??

论坛徽章:
1
射手座
日期:2014-08-04 16:49:43
4 [报告]
发表于 2015-06-29 09:37 |只看该作者
文章只是告诉你 线程池实现的简单方式, 如果考虑那么全, 那么多代码 怎么教学生啊,,要考虑篇幅。

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
5 [报告]
发表于 2015-06-29 09:44 |只看该作者
本帖最后由 yulihua49 于 2015-06-29 09:52 编辑
kkshaq 发表于 2015-06-28 21:20
线程池这个模型还是可以探讨一下啊

消费者和生产者之间同步的问题。。为什么作者不使用真正的共享缓冲 ...

一般是采用context做缓冲区,是每个连接独享的。
采用epoll作为事件队列。
凡是接入的连接,一律加到epoll队列,随后的IO事件都是由epoll处理。可以有多个线程。
epoll队列完成了生产者-消费者模型。
epoll之后的线程数,与核数有关,而与连接数无关。连接数与系统的fd数和应用的context数有关。
连接数超过线程数也没关系,在epoll里等就是了。只有它发生IO时才需要线程。
如果发生IO的连接数超过了线程数,也没关系,等就是了。等到有线程完成了其他任务回来抓事件。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP