当前位置: 技术问答>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状态。
/*
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还没有起作用呢。。。
//sleep(1);
改为 sleep(10);
或者更大 就好了
设置为取消点的时候,主线程中的pthread_setcancelstate还没有起作用呢。。。
|
你不是都设置成失效了吗?
1,2交换和你设置失效又没关系
1,2交换和你设置失效又没关系
|
最下边用pthread_join好了