免费注册 查看新帖 |

Chinaunix

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

[C] 服务器多线程编程,这么写对不对 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-27 21:50 |只看该作者 |倒序浏览
tcp服务器程序:
  1. int main()
  2. {
  3.     .........
  4.     .........
  5.     int listenfd,connectfd;
  6.     char buff[1024];
  7.     pthread_t ptid;
  8.     listenfd=listen(..);


  9.     while(1)
  10.     {
  11.         connectfd=accept( listenfd , struct sockaddr*addr...);
  12.         recv(...,buf,...)
  13.         pthread(&ptid,NULL,fun,(void *) buf);
  14. }

  15.     return 0;
  16. }

  17. void fun(void * buf)
  18. {
  19.   
  20.   printf("%d",(char *) buf);//问题1:线程1进入fun但printf还没调用前,cpu切换到线程2,也就是在第二次accept和receive后,cpu又切换到线程1,但此时buff里面是线程2的数据,如何避免
  21.    
  22. //函数结束时要不要关闭connectfd,close(connectfd)
  23. }
复制代码
udp服务器程序:



int main()
{
    ......
    int fd,ptid;
    char buff[512];
    struct sockaddr_in clientAddr;//用来存储客户端传来的信息
    int n;
    int len = sizeof(clientAddr);
    while(1)
    {
        n = recvfrom(sock, buff, sizeof(buff), 0, (struct sockaddr*)&clientAddr, &len);
        if (n>0)
        {
            pthread_t ptid;
            pthread_create(&ptid,NULL,fun,(void*) clientAddr);
        }

    return 0;
}

void fun(void *arg)
{
   
    printf("%d",(struct sockaddr_in) arg.sin_addr.s_addr);//问题同 问题1
    //函数结束时要不要关闭connectfd,close(connectfd)
}

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
2 [报告]
发表于 2013-08-28 11:06 |只看该作者
回复 1# mrpre


    TCP的问题:
 1、socket没看到设置nonblocking,accept之后把上recv会导致主线程阻塞其它的连接这时将得到不处理,如果连接较多的话问题就更严重了。
 2、没看到使用任何多路复用的事件模型。效率低下
 3、一个连接对应一个线程的方式已成为历史了,除非连接的量非常少。


 UDP的问题:
 和TCP类似。


 总结:这个代码是学习性代码,基本不具备真实环境的实用性(除非程序逻辑简单到了极至)

论坛徽章:
0
3 [报告]
发表于 2013-08-29 09:08 |只看该作者
TCP为例的话,一般是accept后,创建新的线程去recv,也就是说recv的操作应该是在你的fun函数中处理的,所以不会有你说的buf的问题。
如果你使用的是容器或者全局变量,那么去查下“线程锁”
最好还学习上上面说的I/O多路复用,即select/poll/epoll

论坛徽章:
0
4 [报告]
发表于 2013-08-29 10:40 |只看该作者
我连问题都没看懂

论坛徽章:
0
5 [报告]
发表于 2013-08-29 10:44 |只看该作者
学习的代码, accept后fork新的进程处理recv, 就不会冲突。 也不会阻塞主进程处理其它的连接请求。以后可以尝试用IO多路复用.

论坛徽章:
0
6 [报告]
发表于 2013-08-30 07:37 |只看该作者
本帖最后由 redor 于 2013-08-30 07:37 编辑

回复 1# mrpre


    最好是先初始化一堆线程,一个连接来的时候去找空闲线程,用完回收线程

论坛徽章:
0
7 [报告]
发表于 2013-09-03 14:47 |只看该作者
//问题1:线程1进入fun但printf还没调用前,cpu切换到线程2,也就是在第二次accept和receive后,cpu又切换到线程1,但此时buff里面是线程2的数据,如何避免
   


判断cpu状态位;
int i,j;
即epoll 或poll....

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP