linux pthread和java thread的是/非守护线程的行为
Posted jald
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux pthread和java thread的是/非守护线程的行为相关的知识,希望对你有一定的参考价值。
pthread_xxx 的函数并没有直接提供设置一个pthread为守护线程的api
而pthread_attr_init() 和 struct pthread_attr_t 也并没有提供 线程是否被设置为守护线程的成员变量
但java 的线程对象有 setDaemon() 方法将线程设置为守护线程
那我们看看java的Thread的native层是如何实现该变量的功能的
void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) { 。。。 623 Thread* child_thread = new Thread(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<stdio.h> #include<unistd.h> #include<pthread.h> void msleep(unsigned int s){ printf("tid: %d, start sleep %d ",pthread_self(),s); sleep(s); printf("tid: %d, end sleep %d ",pthread_self(),s); } int fun2(){ printf("fun2() start "); pthread_detach(pthread_self()); printf("current tid:%d ",pthread_self()); msleep(5); printf("fun2() end "); return 1; } void main(){ int res; pthread_t pt2; printf("main() start "); //pthread_attr_init(); res = pthread_create(&pt2,NULL,fun2,NULL); //printf("res: %d ",res); msleep(3); printf("main() end "); }
输出
root@ubuntu:~/cdir/dthreaddemo# ./dt1 main() start tid: -1624217856, start sleep 3 fun2() start current tid:-1632536832 tid: -1632536832, start sleep 5 tid: -1624217856, end sleep 3 main() end
可以看到并没有 fun2() end 输出
L2.2.
代码
#include<stdio.h> #include<unistd.h> #include<pthread.h> void msleep(unsigned int s){ printf("tid: %d, start sleep %d ",pthread_self(),s); sleep(s); printf("tid: %d, end sleep %d ",pthread_self(),s); } int fun2(){ printf("fun2() start "); pthread_detach(pthread_self()); printf("current tid:%d ",pthread_self()); msleep(3); printf("fun2() end "); return 1; } void main(){ int res; pthread_t pt2; printf("main() start "); //pthread_attr_init(); res = pthread_create(&pt2,NULL,fun2,NULL); //printf("res: %d ",res); msleep(5); printf("main() end "); }
输出
root@ubuntu:~/cdir/dthreaddemo# ./dt1 main() start tid: -1453377792, start sleep 5 fun2() start current tid:-1461696768 tid: -1461696768, start sleep 3 tid: -1461696768, end sleep 3 fun2() end tid: -1453377792, end sleep 5 main() end
J1.1
代码
public class Test1 { public static void main(String[] args) { System.out.println("main start"); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 start"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2 end"); } }); // t2.isDaemon(); //default is false t2.setDaemon(false); t2.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2.isAlive() " + t2.isAlive()); System.out.println("main end"); } }
输出
main start t2 start t2.isAlive() true main end t2 end Process finished with exit code 0
J1.2.
代码
public class Test1 { public static void main(String[] args) { System.out.println("main start"); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 start"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2 end"); } }); // t2.isDaemon(); //default is false t2.setDaemon(false); t2.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2.isAlive() " + t2.isAlive()); System.out.println("main end"); } }
输出
main start
t2 start
t2 end
t2.isAlive() false
main end
Process finished with exit code 0
J2.1.
代码
public class Test1 { public static void main(String[] args) { System.out.println("main start"); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 start"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2 end"); } }); // t2.isDaemon(); //default is false t2.setDaemon(true); t2.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2.isAlive() " + t2.isAlive()); System.out.println("main end"); } }
输出
main start t2 start t2.isAlive() true main end Process finished with exit code 0
J2.2.
代码
public class Test1 { public static void main(String[] args) { System.out.println("main start"); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println("t2 start"); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2 end"); } }); // t2.isDaemon(); //default is false t2.setDaemon(true); t2.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t2.isAlive() " + t2.isAlive()); System.out.println("main end"); } }
输出
main start t2 start t2 end t2.isAlive() false main end Process finished with exit code 0
这里不考虑线程调度的极端问题,如活锁之类的,或导致某个线程一致无法被分配到时间片等情况。
以上是关于linux pthread和java thread的是/非守护线程的行为的主要内容,如果未能解决你的问题,请参考以下文章
linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)
linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)
linux pthreads 上的 gcc 4.7 - 使用 __thread 的重要 thread_local 解决方法(无提升)