linux非守护线程一直不释放,Linux pthread 和 java thread 的是 / 非守护线程的行为
Linux pthread 和 java thread 的是 / 非守護線程的行為
pthread_xxx 的函數并沒有直接提供設置一個 pthread 為守護線程的 API
而 pthread_attr_init() 和 struct pthread_attr_t 也并沒有提供 線程是否被設置為守護線程的成員變量
但 java 的線程對象有 setDaemon() 方法將線程設置為守護線程
那我們看看 java 的 Thread 的 native 層是如何實現該變量的功能的voidThread::CreateNativeThread(JNIEnv*env,jobject java_peer,size_tstack_size,boolis_daemon){
...
623Thread*child_thread=newThread(is_daemon);// is_daemon 是關鍵
...
好像和 native 的 pthread 并沒有什么關系... 可能和 jvm 里有相關處理邏輯.
所以說 Linux 下是不存在原生的 pthread 是否為守護進程概念的 (最多只有守護進程概念)
Linux 下 pthread 行為:
L1. 子線程為守護線程 (默認情況, Linux 下創建 pthread 天生就是守護線程, 行為和 J2. java 中調用 setDaemon(true) 后一致):
1.mainThread 跑完 main 函數, subThread 立刻退出, mainThread 退出, 整個進程退出
2.subThread 跑完, subThread 退出, mainThread 跑完 main 函數, mainThread 退出, 整個進程退出
java 下 thread 行為:
J1. 子線程不為守護線程 (默認情況, java 下創建 thread 天生不是守護進程):
1.mainThread 跑完 main 函數, subThread 立刻退出, mainThread 退出, jvm 退出, 進程退出
2.subThread 跑完, subThread 退出, mainThread 跑完 main 函數, mainThread 退出, jvm 退出, 進程退出
J2. 子線程為守護線程 (調用 setDaemon(true), 和 Linux 下子線程創建后, 行為和 Linux 中默認創建 pthread 后一致):
1.mainThread 跑完 main 函數, subThread 繼續跑到退出, subThread 退出, mainThread 退出, jvm 退出, 進程退出
2.subThread 跑完, subThread 退出, mainThread 跑完 main 函數, mainThread 退出, jvm 退出, 進程退出
總結
1. 守護線程行為
Linux 下默認創建線程 = java 下創建后調用 setDeamon(true)
行為: 只要主線程執行完了, 守護線程立刻銷毀, 進程退出
2. 非守護線程行為
Linux 下無法直接將線程設置為非守護進程 = java 下默認創建的線程默認就是非守護線程
行為: 任何一個非守護線程執行完了, 立刻銷毀自己 (無論主線程還是子線程), 整個進程中非守護進程數量 > 0, 進程不會退出; 整個進程中非守護進程數量 == 0, 立刻剩余銷毀守護進程, 并退出進程
L1 代碼:
L1.1.#include
#include
#include
voidmsleep(unsignedints){
printf("tid: %d, start sleep %d\n",pthread_self(),s);
sleep(s);
printf("tid: %d, end sleep %d\n",pthread_self(),s);
}
intfun2(){
printf("fun2() start\n");
pthread_detach(pthread_self());
printf("current tid:%d\n",pthread_self());
msleep(5);
printf("fun2() end\n");
return1;
}
voidmain(){
intres;
pthread_tpt2;
printf("main() start\n");
//pthread_attr_init();
res=pthread_create(&pt2,NULL,fun2,NULL);
//printf("res: %d\n",res);
msleep(3);
printf("main() end\n");
}
輸出[emailprotected]:~/cdir/dthreaddemo# ./dt1
main()start
tid:-1624217856,start sleep3
fun2()start
current tid:-1632536832
tid:-1632536832,start sleep5
tid:-1624217856,endsleep3
main()end
可以看到并沒有 fun2() end 輸出
L2.2.
代碼#include
#include
#include
voidmsleep(unsignedints){
printf("tid: %d, start sleep %d\n",pthread_self(),s);
sleep(s);
printf("tid: %d, end sleep %d\n",pthread_self(),s);
}
intfun2(){
printf("fun2() start\n");
pthread_detach(pthread_self());
printf("current tid:%d\n",pthread_self());
msleep(3);
printf("fun2() end\n");
return1;
}
voidmain(){
intres;
pthread_tpt2;
printf("main() start\n");
//pthread_attr_init();
res=pthread_create(&pt2,NULL,fun2,NULL);
//printf("res: %d\n",res);
msleep(5);
printf("main() end\n");
}
輸出[emailprotected]:~/cdir/dthreaddemo# ./dt1
main()start
tid:-1453377792,start sleep5
fun2()start
current tid:-1461696768
tid:-1461696768,start sleep3
tid:-1461696768,endsleep3
fun2()end
tid:-1453377792,endsleep5
main()end
J1.1
代碼publicclassTest1{
publicstaticvoidmain(String[]args){
System.out.println("main start");
Threadt2=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("t2 start");
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2 end");
}
});
// t2.isDaemon(); //default is false
t2.setDaemon(false);
t2.start();
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2.isAlive()"+t2.isAlive());
System.out.println("main end");
}
}
輸出main start
t2 start
t2.isAlive()true
mainend
t2end
Processfinishedwithexitcode0
J1.2.
代碼publicclassTest1{
publicstaticvoidmain(String[]args){
System.out.println("main start");
Threadt2=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("t2 start");
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2 end");
}
});
// t2.isDaemon(); //default is false
t2.setDaemon(false);
t2.start();
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2.isAlive()"+t2.isAlive());
System.out.println("main end");
}
}
輸出main start
t2 start
t2end
t2.isAlive()false
mainend
Processfinishedwithexitcode0
J2.1.
代碼publicclassTest1{
publicstaticvoidmain(String[]args){
System.out.println("main start");
Threadt2=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("t2 start");
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2 end");
}
});
// t2.isDaemon(); //default is false
t2.setDaemon(true);
t2.start();
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2.isAlive()"+t2.isAlive());
System.out.println("main end");
}
}
輸出main start
t2 start
t2.isAlive()true
mainend
Processfinishedwithexitcode0
J2.2.
代碼publicclassTest1{
publicstaticvoidmain(String[]args){
System.out.println("main start");
Threadt2=newThread(newRunnable(){
@Override
publicvoidrun(){
System.out.println("t2 start");
try{
Thread.sleep(3000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2 end");
}
});
// t2.isDaemon(); //default is false
t2.setDaemon(true);
t2.start();
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("t2.isAlive()"+t2.isAlive());
System.out.println("main end");
}
}
輸出main start
t2 start
t2end
t2.isAlive()false
mainend
Processfinishedwithexitcode0
這里不考慮線程調度的極端問題, 如活鎖之類的, 或導致某個線程一致無法被分配到時間片等情況.
來源: http://www.bubuko.com/infodetail-3388958.html
總結
以上是生活随笔為你收集整理的linux非守护线程一直不释放,Linux pthread 和 java thread 的是 / 非守护线程的行为的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 土豪金100怎么扫凤凰(土豪可以有多任性
- 下一篇: c语言中strstr函数的用法是什么?(