免费注册 查看新帖 |

Chinaunix

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

[C] 在使用pthread_cancel函数取消线程的时候会出现断错误,有人遇到过么?求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-08 17:43 |只看该作者 |倒序浏览
  1. /* example5.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <pthread.h>                                                /* 包含相关函数头文件 */

  6. void mythread()                                                                 /* 定义新线程运行的函数 */
  7. {
  8.   int i,ret;
  9.   ret = pthread_setcancelstate(                                                /* 设置线程的取消状态 */
  10.         PTHREAD_CANCEL_ENABLE, NULL);
  11.   if(ret != 0)
  12.   {
  13.     printf("Thread pthread_setcancelsate failed.");                /* 如果取消状态未设置成功,打印错误信息 */
  14.     exit(1);
  15.   }
  16.   ret = pthread_setcanceltype(                                                /* 设置线程的取消类型 */
  17.         PTHREAD_CANCEL_DEFERRED, NULL);
  18.   if(ret != 0)
  19.   {
  20.     printf("Thread pthread_setcanceltype failed.");                 /* 如果取消类型未设置成功,打印错误信息 */
  21.     exit(1);
  22.   }

  23.   for(i=0; i<5; i++)                                                                /* 连续输出字符串,同时显示运行位置 */
  24.   {
  25.     printf("Thread is running (%d) ...\n",i);
  26.     sleep(1);
  27.   }
  28.   //pthread_exit("Thank you for the CPU time.\n");                /* 终止当前线程 */
  29. }

  30. int main()
  31. {
  32.   pthread_t id;                                                                 /* 定义线程的标识符 */
  33.   int ret;
  34.   void *thread_result;                                                        /* 定义指针,用来存储线程的返回值 */
  35.   ret = pthread_create(&id, NULL, (void *)mythread, NULL);                                 /* 创建新的线程 */
  36.   if(ret != 0)
  37.   {
  38.     printf("Create pthread error.\n");                                        /* 如果线程创建失败,打印错误信息 */
  39.     exit(1);
  40.   }
  41.   sleep(3);
  42.   printf("Canceling thread ...\n");
  43.   ret = pthread_cancel(id);                                                /* 取消新建线程 */
  44.   if(ret != 0)
  45.   {
  46.     printf("Thread cancelation failed.\n");                                /* 如果线程取消失败,打印错误信息 */
  47.     exit(1);
  48.   }
  49.   sleep(2);
  50.   /* 主线程阻塞,等待新建线程返回,并将返回值存储在前面定义的thread_result之中 */
  51.   pthread_join(id,&thread_result);
  52.   printf("Thread joined, it returned: %s", (char *)thread_result);                /* 输出线程返回的字符串 */
  53.   return 0;
  54. }
复制代码
运行的结果
  1. ./example5
  2. Thread is running (0) ...
  3. Thread is running (1) ...
  4. Thread is running (2) ...
  5. Canceling thread ...
  6. 段错误 (核心已转储)
复制代码
希望知道怎么解决的大侠帮助!

论坛徽章:
0
2 [报告]
发表于 2012-11-08 20:41 |只看该作者
printf("Thread joined, it returned: %s", (char *)thread_result);  的问题。

论坛徽章:
0
3 [报告]
发表于 2012-11-08 20:43 |只看该作者
在 mythread() 中:
pthread_exit("Thank you for the CPU time.\n");

"Thank you for the CPU time.\n"这个字符串在 mythread() 退出后,就无效了。

在 main() 中:
pthread_join(id,&thread_result);
指针thread_result得到的地址是无效的地址,这个指针相当于野指针。

论坛徽章:
0
4 [报告]
发表于 2012-11-08 20:52 |只看该作者
本帖最后由 lc-soft 于 2012-11-08 20:56 编辑

刚刚测试了一下,你都用pthread_cancel()撤销线程了,那么你在main()函数中用pthread_join()函数得到的指针thread_result是指向无效的地址。

mythread()   里,才循环3次,打印了3次Thread is running (%d) ...,就被撤销,线程没有正常的返回值。

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
5 [报告]
发表于 2012-11-10 12:55 |只看该作者
If the target thread was canceled, then PTHREAD_CANCELED is placed in *retval.

同学, 不是每个返回的void*都是字符串.

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
6 [报告]
发表于 2012-11-10 12:58 |只看该作者
  1. /* example5.c */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <pthread.h>                                                /* 包含相关函数头文件 */

  6. void* mythread(void *)                                                                 /* 定义新线程运行的函数 */
  7. {
  8.   int i,ret;
  9.   ret = pthread_setcancelstate(                                                /* 设置线程的取消状态 */
  10.         PTHREAD_CANCEL_ENABLE, NULL);
  11.   if(ret != 0)
  12.   {
  13.     printf("Thread pthread_setcancelsate failed.");                /* 如果取消状态未设置成功,打印错误信息 */
  14.     exit(1);
  15.   }
  16.   ret = pthread_setcanceltype(                                                /* 设置线程的取消类型 */
  17.         PTHREAD_CANCEL_DEFERRED, NULL);
  18.   if(ret != 0)
  19.   {
  20.     printf("Thread pthread_setcanceltype failed.");                 /* 如果取消类型未设置成功,打印错误信息 */
  21.     exit(1);
  22.   }

  23.   for(i=0; i<5; i++)                                                                /* 连续输出字符串,同时显示运行位置 */
  24.   {
  25.     printf("Thread is running (%d) ...\n",i);
  26.     sleep(1);
  27.   }
  28.   pthread_exit((void *)"Thank you for the CPU time.\n");                /* 终止当前线程 */
  29. }

  30. int main()
  31. {
  32.   pthread_t id;                                                                 /* 定义线程的标识符 */
  33.   int ret;
  34.   void *thread_result;                                                        /* 定义指针,用来存储线程的返回值 */
  35.   ret = pthread_create(&id, NULL, mythread, NULL);                                 /* 创建新的线程 */
  36.   if(ret != 0)
  37.   {
  38.     printf("Create pthread error.\n");                                        /* 如果线程创建失败,打印错误信息 */
  39.     exit(1);
  40.   }
  41.   sleep(3);
  42.   printf("Canceling thread ...\n");
  43.   ret = pthread_cancel(id);                                                /* 取消新建线程 */
  44.   if(ret != 0)
  45.   {
  46.     printf("Thread cancelation failed.\n");                                /* 如果线程取消失败,打印错误信息 */
  47.     exit(1);
  48.   }
  49.   sleep(2);
  50.   /* 主线程阻塞,等待新建线程返回,并将返回值存储在前面定义的thread_result之中 */
  51.   pthread_join(id,&thread_result);
  52.    
  53. if (thread_result == PTHREAD_CANCELED )
  54. {
  55.     printf("cancel\n");                /* 输出线程返回的字符串 */
  56. }
  57. else
  58. {
  59. printf("Thread joined, it returned: %s", (char *)thread_result);
  60. }
  61.    
  62.   return 0;
  63. }
复制代码
linux_c_py_php 发表于 2012-11-10 12:55
If the target thread was canceled, then PTHREAD_CANCELED is placed in *retval.

同学, 不是每个返回 ...


还有, 代码规范点, 线程函数是那么定义的吗?

论坛徽章:
0
7 [报告]
发表于 2012-11-11 12:08 |只看该作者
回复 3# lc-soft 确实是这样的,我当初还以为只是结束了那个线程而已 后来都改到函数库里面去了,我以为是溢出了,把进程从long型改为了long long型后来还真编译过了,就是结束线程的返回值乱码了。


   

论坛徽章:
0
8 [报告]
发表于 2012-11-11 12:09 |只看该作者
回复 6# linux_c_py_php 额,就根书学了,以后一定改


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP