免费注册 查看新帖 |

Chinaunix

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

[C++] 多线程问题 [复制链接]

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-10-21 12:53 |只看该作者 |倒序浏览
请问各位大侠,我下面的设计在什么地方有问题?

我在主线程当中开了另外2个线程,flushData和printData(死循环)

flushData(不是死循环)当中开了readKeyBoardValue(死循环)和十几个getQpidInfo线程(死循环)

在readKeyBoardValue当中实时监控键盘指令,如果按q,就发pthread_kill给主线程,主线程内吧flushData,printData,和readKeyBoardValue,和十几个getQpidInfo线程依次用pthread_cancel关闭,然后主线程用pthread_exit()退出。

现在这么做产生了core dump,

#0  0x0000003b99a328a5 in raise () from /lib64/libc.so.6
#1  0x0000003b99a34085 in abort () from /lib64/libc.so.6
#2  0x0000003b99e0dcb1 in unwind_cleanup () from /lib64/libpthread.so.0
#3  0x0000000000416fe4 in main (argc=3, argv=0x7fffffff8da at src/route-tool.cpp:150

请问这什么情况啊。

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
2 [报告]
发表于 2013-10-21 12:58 |只看该作者
我把主线程最后一句pthread_exit去掉就不出core dump了。。

论坛徽章:
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
3 [报告]
发表于 2013-10-21 13:43 |只看该作者
回复 1# bottles


    让线程正常退出是最好的方法,尽量让每个线程都可以通过检查某些状态尽正常退出。使用pthread_cancel是相当不安全的。pthread_cancel在Asynchronous模式下只能cancel掉Asynchronous cancelability的系统调用(系统不能保证一定可以立刻cancel掉),在Deferred cancelability模式下只能运行到某些cancellation point才能退出,不是所有系统调用(or函数)都支持cancellation point,所以退出的点也存在疑问。除非你把这些问题都搞明白,不然cancel的行为是存在不确定性的。

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
4 [报告]
发表于 2013-10-21 14:36 |只看该作者
回复 3# myworkstation


    除了应用pthread_cancel,还能怎么让线程退出呢?现在需求就是需要从外部命令当中获取消息,全部得到之后吧这些信息打印出来,这个过程是持续的,然后过程当中按q直接退出,我设计的就是按q这个监控的过程一个线程(死循环),打印消息一个线程(死循环),获得消息n个线程(死循环),当所有消息获得之后,最后一个获得信息的线程发一个cond_signal到打印消息的线程,打印消息的线程一开始一直是cond_wait,然后得到signal之后就开始打印。监控键盘按键消息的线程获得退出消息之后发送signal给主线程,主线程记录了所有打开线程的线程id,然后发送pthread_cancel. 对了在每个死循环的线程当中我也添加了pthread_testcancel,就8知道有没有用了。。

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
5 [报告]
发表于 2013-10-21 14:41 |只看该作者
回复 3# myworkstation


    我再好好研究pthread_cancel的使用吧,谢谢回答。

论坛徽章:
1
综合交流区版块每日发帖之星
日期:2015-10-14 06:20:00
6 [报告]
发表于 2013-10-21 14:44 |只看该作者
本帖最后由 fly3ds 于 2013-10-21 14:56 编辑

回复 4# bottles

涉及到信号的问题是比较麻烦,首先信号在进程收到信号后的默认动作数在不同的系统上就未必完全一样,也不会同书中手册中写的一样,写书或者写manual的人到底在那些个系统哪个版本上真正试过那些东西就很值得怀疑,即使是大名鼎鼎的APUE也不列外。书中的程序可能在当时的系统上是正确的,在今天的各种Unix系统上很大可能是错的。放到线程上,这个问题就更复杂了。

要我说就是不要用pthread_kill, pthread_cancel这类东西,这些对于我来说都是设计过于复杂,另外想好弄的办法吧。我记得比较正常常规的退出线程办法是主线程中调用用pthread_join来回收其他线程。

论坛徽章:
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
7 [报告]
发表于 2013-10-21 14:47 |只看该作者
回复 4# bottles


    把线程中所有的死循环改条件改成检查(volatile int)变量isq,只要isq改变了那么就退了线程循环(当q键被按下的时候变量isq状态被修改),这样子线程不是很正常的终止了吗?

论坛徽章:
5
双鱼座
日期:2013-11-26 17:56:26狮子座
日期:2013-11-29 15:41:32处女座
日期:2014-02-21 11:59:07技术图书徽章
日期:2014-03-06 15:33:53技术图书徽章
日期:2014-03-06 15:39:30
8 [报告]
发表于 2013-10-21 15:28 |只看该作者
本帖最后由 bottles 于 2013-10-21 15:30 编辑

回复 7# myworkstation


    看到好多人都说pthread_cancel有风险额,但是具体会是什么问题造成的呢?看了下文档,上面说:“A  condition  wait,  whether  timed or not, is a cancellation point. ”,也就是说当cond_wait的时候可以正常响应pthread_cancel的,在看下pthread_cancel的文档:"A thread is cancellation type, determined by pthread_setcanceltype(3), may be either asynchronous or  deferred  (the  default  for  new
       threads). ""也就是说线程默认是deferred类型的,这样看起来我的程序也没设计问题啊。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
9 [报告]
发表于 2013-10-21 16:03 |只看该作者
工作线程里的循环里时不时的去查寻一个“是否结束”的变量, 如果要结束,那就结束当前工作,正常退出。  主线程可以设置这个变量来通知工作线程退出。

论坛徽章:
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
10 [报告]
发表于 2013-10-21 16:26 |只看该作者
回复 8# bottles


    你要取消的线程都在condition  wait时才cancel的吗?要不然只说这个也没什么意义。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP