当前位置:  技术问答>linux和unix

为什么没取消线程啊?

    来源: 互联网  发布时间:2016-12-23

    本文导语:  /*********************************************************************************/ /* pthread_cancel取消线程。 取消状态: 1。PTHREAD_CANCEL_ENABLE 0 可取消 2。PTHREAD_CANCEL_DISABLE 1 不取消 取消类型: 1。PTHREAD_CANCEL_DEFERRED 0 延迟取消(直到找到...


/*********************************************************************************/
/*
pthread_cancel取消线程。
取消状态:
1。PTHREAD_CANCEL_ENABLE 0 可取消
2。PTHREAD_CANCEL_DISABLE 1 不取消
取消类型:
1。PTHREAD_CANCEL_DEFERRED 0 延迟取消(直到找到取消点,线程结束)
2。PTHREAD_CANCEL_ASYNCHRONOUS 1 异步取消(任意时刻结束)
*/
/********************************************************************************/

#include 
#include 
#include 
#include 

void * fun(void * arg)
{
printf("in pthread start:n");
//sleep(1);
pthread_testcancel(); //设置为取消点
printf("in pthread end:n");
return (void *)0;

}

int main()
{
pthread_t tid1;
int err;
int oldstate;

if ((err = pthread_create(&tid1, NULL, fun, NULL)) != 0)
{
printf("pthread1 error!n");
}

// 0 1
printf("%d %dn", PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE);

if (pthread_setcancelstate(0, &oldstate) != 0) //设置为延迟取消
{
printf("pthread_setcancelstate error!n");
}
printf("%dn", oldstate);


sleep(1); //如果主线程运行完了,子线程没运行完就结束了。--------(1)
pthread_cancel(tid1);  //取消某线程-----------------------------------------------(2)

printf("in main pthread:n");


return 0;
}

结果:
[root@localhost work1]# ./1                               //原程序
0 1
0
in pthread start:
in pthread end:
in main pthread:
[root@localhost work1]# gcc 1.c -o 1 -lpthread            //(1) 和(2)交换
[root@localhost work1]# ./1
0 1
0
in pthread start:
in pthread end:
in main pthread:
[root@localhost work1]# gcc 1.c -o 1 -lpthread          //(1) 和(2)交换, sleep(5)会永远阻塞
[root@localhost work1]# ./1
0 1
0

[root@localhost work1]# 
上面是什么原因啊? 我设置成取消失效时,结果不变。



|
/*********************************************************************************/
/*
    pthread_cancel取消线程。
    取消状态:
        1。PTHREAD_CANCEL_ENABLE            0    可取消
        2。PTHREAD_CANCEL_DISABLE        1    不取消
    取消类型:
        1。PTHREAD_CANCEL_DEFERRED        0    延迟取消(直到找到取消点,线程结束)
        2。PTHREAD_CANCEL_ASYNCHRONOUS        1    异步取消(任意时刻结束)
*/
/********************************************************************************/

#include 
#include 
#include 
#include 

void * fun(void * arg)
{
    int oldstate;       
   if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate) != 0)        ///设置取消线程
    {
        printf("pthread_setcancelstate error!n");
    }
    printf("set PTHREAD_CANCEL_ENABLE,oldstate=%dn", oldstate);
   
    
/*   if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0)        //设置不取消线程
    {
        printf("pthread_setcancelstate error!n");
    }
    printf("set PTHREAD_CANCEL_DISABLE,oldstate=%dn", oldstate);
*/
   printf("in pthread start,pthread_id=%dn",pthread_self());
   printf("in pthread before testcanceln");
   while(1)
   {
        pthread_testcancel();                              //设置为取消点
        printf("in pthread continuen");
        sleep(1);
   }
   printf("pthread endn");
   return (void *)0;
    
}

int main()
{
    pthread_t tid;
    int err;
    int oldstate;
    
    if ((err = pthread_create(&tid, NULL, fun, NULL)) != 0)
    {
        printf("pthread1 error!n");
    }    
    
    // 0    1
    printf("PTHREAD_CANCEL_ENABLE=%d PTHREAD_CANCEL_DISABLE=%dn", PTHREAD_CANCEL_ENABLE, PTHREAD_CANCEL_DISABLE);
    
    printf("oldstate=%d,tid=%dn", oldstate,tid);

    /*if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate) != 0)        //设置取消线程
    {
        printf("pthread_setcancelstate error!n");
    }
    printf("set PTHREAD_CANCEL_ENABLE,oldstate=%dn", oldstate);
    */
    
    
    /*if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate) != 0)        //设置不取消线程
    {
        printf("pthread_setcancelstate error!n");
    }
    printf("set PTHREAD_CANCEL_DISABLE,oldstate=%dn", oldstate);
    */
    

    sleep(20);
    printf("in main cancel pthread,tid=%dn",tid );
    pthread_cancel(tid);  //取消某线程

    while(1)
    {
      printf("in main continuen");
      sleep(2);            
    }
    
    
    printf("in main pthreadn");

    
    return 0;
}
如上代码,可以测试出设置线程取消属性后pthread_testcancel();是否生效。


测试方案:设置PTHREAD_CANCEL_ENABLE时。
日志打印:./thread 
PTHREAD_CANCEL_ENABLE=1 PTHREAD_CANCEL_DISABLE=0
set PTHREAD_CANCEL_ENABLE,oldstate=1
oldstate=2147481144,tid=2
in pthread start,pthread_id=2
in pthread before testcancel
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in main cancel pthread,tid=2
in main continue
in main continue
in main continue
in main continue
in main continue
in main continue
in main continue
in main continue
即线程开始一直运行直到mian调用到pthread_cancel后main开始打印“in main continue
”但是pthread不在打印“in pthread continue”,因为都是死循环,因此说明fun线程已经被注销了。
同时我使用pstack看了一下过程:
在调用pthread_cancel前:
pstack 5931 
5931:   ./thread

--------------------------------  lwpid : 4121435   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 0000000004001390 : main() + 0x1e0 (./thread)
 4: 60000000c0030390 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)

--------------------------------  lwpid : 4121439   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 0000000004001020 : _Z3funPv() + 0x2d0 (./thread)
 4: 60000000c00f69a0 : __pthread_bound_body() + 0x190 (/usr/lib/hpux32/libpthread.so.1)
说明有二个线程,即一个主,一个子。
调用完毕pthread_cancel后:
pstack 5931 
5931:   ./thread

--------------------------------  lwpid : 4121435   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 00000000040014e0 : main() + 0x330 (./thread)
 4: 60000000c0030390 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so) 
说明只有一个线程了。则设置的属性PTHREAD_CANCEL_ENABLE
生效,线程被kill掉。

将取消属性设置为:PTHREAD_CANCEL_DISABLE
打印过程:
./thread 
set PTHREAD_CANCEL_DISABLE,oldstate=1
in pthread start,pthread_id=2
in pthread before testcancel
in pthread continue
PTHREAD_CANCEL_ENABLE=1 PTHREAD_CANCEL_DISABLE=0
oldstate=2147481144,tid=2
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in pthread continue
in main cancel pthread,tid=2
in main continue
in pthread continue
in pthread continue
in main continue
in pthread continue
in pthread continue
in main continue
in pthread continue
in pthread continue
in main continue
in pthread continue
in pthread continue
in main continue
in pthread continue
in pthread continue
in main continue
in pthread continue
即main调用了pthread_cancel后fun和main交叉打印日志,说明线程一直是活着的。
同时用pstack看打开线程数:
调用pthread_cancel前:
pstack 28106 
28106:  ./thread

--------------------------------  lwpid : 4113266   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 00000000040014e0 : main() + 0x330 (./thread)
 4: 60000000c0030390 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)

--------------------------------  lwpid : 4113267   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 0000000004001020 : _Z3funPv() + 0x2d0 (./thread)
 4: 60000000c00f69a0 : __pthread_bound_body() + 0x190 (/usr/lib/hpux32/libpthread.so.1)

调用pthread_cancel后:
pstack 28106 
28106:  ./thread

--------------------------------  lwpid : 4113266   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 00000000040014e0 : main() + 0x330 (./thread)
 4: 60000000c0030390 : main_opd_entry() + 0x50 (/usr/lib/hpux32/dld.so)

--------------------------------  lwpid : 4113267   -------------------------------

 0: 60000000c0433b10 : _nanosleep2_sys() + 0x30 (/usr/lib/hpux32/libc.so.1)
 1: 60000000c0444840 : __nanosleep2() + 0xc0 (/usr/lib/hpux32/libc.so.1)
 2: 60000000c02dbcc0 : sleep() + 0x410 (/usr/lib/hpux32/libc.so.1)
 3: 0000000004001020 : _Z3funPv() + 0x2d0 (./thread)
 4: 60000000c00f69a0 : __pthread_bound_body() + 0x190 (/usr/lib/hpux32/libpthread.so.1)
说明前后都是二个线程。即pthread_cancel设置PTHREAD_CANCEL_DISABLE
未生效。线程未被kill。
main中我设置了较长的sleep时间,是为了晚点调用pthread_cancel便于查看pstack状态。

|
实际上你的 分析是好的,你把

//sleep(1);

改为 sleep(10); 
或者更大 就好了


设置为取消点的时候,主线程中的pthread_setcancelstate还没有起作用呢。。。

|
你不是都设置成失效了吗?
1,2交换和你设置失效又没关系

|
最下边用pthread_join好了

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • HP-UX如何取消用户的root权限?可自我取消吗?
  • 关于RMI中取消激活的困惑
  • 关于多进程同时从消息队列取消息的问题
  • VI中怎样取消高亮显示
  • LINUX如何取消系统启动时对键盘和鼠标的自检?
  • 内核RTC同步怎么取消??
  • jquery操作checkbox实现全选和取消全选
  • jquery easyui easyui-datetimebox 取消用户输入
  • 怎样取消一个正在打印的作业?
  • 用alias定义的别名怎么取消?
  • 编写QT程序中的QListView的排序功能如何取消?
  • 如何取消开机时的时间服务器同步?
  • 所有文件用vim打开后 “>”(大于号)都变成高亮显示 不知如何取消?
  • 求助 如何取消fedora 8启动时候的欢迎应用程序
  • tree 如何取消选择
  • opensuse如何 取消开机 自动登录 ?
  • 如何取消ctrl+alt+f1以及alt+f4等系统默认的功能快捷键
  • 如何将VI这种一打开就出现的色块取消掉
  • svn取消版本控制
  • 跪求!!!怎么取消SUSE的自动安装


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3