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 的是 / 非守护线程的行为相关推荐

  1. linux查看端口被占用且释放,Linux查看端口占用情况,并强制释放占用的端口

    1.查找被占用的端口 netstat -tln netstat -tln | grep 8080 netstat -tln 查看端口使用情况,而netstat -tln | grep 8080则是只查 ...

  2. java 销毁线程_线程 学习教程(一): Java中终止(销毁)线程的方法

    结束线程有以下三种方法: (1)设置退出标志,使线程正常退出,也就是当run()方法完成后线程终止 (2)使用interrupt()方法中断线程 (3)使用stop方法强行终止线程(不推荐使用,Thr ...

  3. linux取消挂载并将分区释放,Linux硬盘、分区、挂载、删除

    Linux硬盘.分区.挂载.删除 一. 磁盘的简介 1.硬盘的接口 ①IDE :比较老的接口,很多针脚,现在基本被淘汰了. ②SAS : 服务器上一般用这个.SAS接口的硬盘比SATA接口的硬盘传输速 ...

  4. linux取消挂载并将分区释放,linux硬盘分区:分区,格式化,挂载,取消挂载,删除分区...

    1.创建分区 先查看是否有未分区的硬盘存在 # fdisk -l 上图中,原硬盘已分区格式化挂载,新硬盘没有分区 so,开始分区 # fdisk /dev/sdb 输入m可以查看各个命令选项 输入p, ...

  5. go和java线程,Go的多线程和pthread或Java线程有什么区别?

    正如之前的答案所述,go例程并不一定与系统线程相对应,但是如果你现在必须提高多线程的性能,我发现以下内容很有用: The current implementation of the Go runtim ...

  6. java thread 几个状态_Java-Thread 线程的几种状态

    Oracle JDK 定义中,线程一共有六种状态 NEW:未启动状态 Thread t= newThread() { @Overridepublic voidrun() { System.out.pr ...

  7. Java多线程学习六:使用线程池比手动创建线程好在那里以及常用线程池参数的意义

    为什么要使用线程池 首先,回顾线程池的相关知识,在 Java 诞生之初是没有线程池的概念的,而是先有线程,随着线程数的不断增加,人们发现需要一个专门的类来管理它们,于是才诞生了线程池.没有线程池的时候 ...

  8. 【Linux开发】彻底释放Linux线程的资源

    Linux系统中程序的线程资源是有限的,表现为对于一个程序其能同时运行的线程数是有限的.而默认的条件下,一个线程结束后,其对应的资源不会被释放,于是,如果在一个程序中,反复建立线程,而线程又默认的退出 ...

  9. linux守护进程中多线程实现,Linux下实现多线程客户/服务器

    在传统的Unix模型中,当一个进程需要由另一个实体执行某件事时,该进程派生(fork)一个子进程,让子进程去进行处理. Unix下的大多数网络服务器程序都是这么编写的,即父进程接受连接,派生子进程,子 ...

最新文章

  1. 如何进行相机的绝对位置估计?
  2. IC基础知识(1)集成电路(IC)简介
  3. 【PAT乙级】1061 判断题 (15 分)
  4. lucene和elasticsearch的前世今生、elasticsearch的核心概念、elasticsearch核心概念 vs. 数据库核心概念(来自学习资料)
  5. java虚拟机内存空间
  6. easypoi 多sheet导入_快速Office,PDF 开发 工具 EasyPoi
  7. java 从一个容器获取对象,如何从 Spring IoC 容器中获取对象?
  8. [Everyday Mathematics]20150225
  9. Gravatar - globally recognized avatar
  10. [Java] java打飞机小游戏
  11. 虚拟机连接锐捷校园网
  12. 知识关联视角下金融证券知识图谱构建与相关股票发现
  13. 无人机DLG生产作业流程
  14. python初学火车座位判断_初学Python实现学校图书馆座位自动抢座预约
  15. python跟excle公式区别_python – numpy.std和excel STDEV函数有什么区别吗?
  16. 电脑底部的任务栏跑左侧了怎么调 windows
  17. 亚马逊6页纸开会方法!
  18. 非线性规划的拉格朗日乘子法python编程python包编程
  19. 用 typescript 做一个贪吃蛇小游戏
  20. sdk是什么意思_学好前端的6点建议,企业需要什么样的Web前端人才?

热门文章

  1. SAP Spartacus B2B 页面 info icon 设计 - 版本1.0
  2. SAP CRM One Order函数CRM_Object_FILL_OW的设计原理
  3. Wordpress的theme存储位置
  4. SAP Cloud for Customer根据模型某字段进行OData的搜索操作
  5. SAP UI5 different cache results
  6. SAP Fiori My note应用的add to功能的后台ABAP实现
  7. CRM and Saptest1 Fiori UI共存的一个典型例子
  8. 如何找到cache-control header是从后台何处设置的
  9. 如何找出Fiori frontend server的systen ID
  10. SAP云平台cf push命令报错误码44的解决方法