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\n",pthread_self(),s);
    sleep(s);
    printf("tid: %d, end sleep %d\n",pthread_self(),s);
}

int fun2(){
    printf("fun2() start\n");
    pthread_detach(pthread_self());
    printf("current tid:%d\n",pthread_self());
    msleep(5);
    printf("fun2() end\n");
    return 1;
}

void main(){
    int res;
    pthread_t pt2;

    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");
}

输出

[email protected]:~/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\n",pthread_self(),s);
    sleep(s);
    printf("tid: %d, end sleep %d\n",pthread_self(),s);
}

int fun2(){
    printf("fun2() start\n");
    pthread_detach(pthread_self());
    printf("current tid:%d\n",pthread_self());
    msleep(3);
    printf("fun2() end\n");
    return 1;
}

void main(){
    int res;
    pthread_t pt2;

    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");
}

输出

[email protected]:~/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

这里不考虑线程调度的极端问题,如活锁之类的,或导致某个线程一致无法被分配到时间片等情况。

原文地址:https://www.cnblogs.com/cyy12/p/12216411.html

时间: 2024-11-29 10:56:48

linux pthread和java thread的是/非守护线程的行为的相关文章

Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面: 即如何使用Thread+Handler的方式从非UI线程发送界面更新消息到UI线程. 概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainThread),

Java中的守护线程和非守护线程(转载)

<什么是守护线程,什么是非守护线程> Java有两种Thread:“守护线程Daemon”(守护线程)与“用户线程User”(非守护线程). 用户线程:非守护线程包括常规的用户线程或诸如用于处理GUI事件的事件调度线程,Java虚拟机在它所有非守护线程已经离开后自动离开. 守护线程:守护线程则是用来服务用户线程的,比如说GC线程.如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去.(操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构建在JVM

Android异步处理系列文章四篇之一使用Thread+Handler实现非UI线程更新UI界面

目录: Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Looper+MessageQueue深入详解Android异步处理四:AsyncTask的实现原理 Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 概述:每个Android应用程序都运行在一个dalvik虚拟机进程中,进程开始的时候会启动一个主线程(MainTh

[Java基础] java的守护线程与非守护线程

最近重新研究Java基础知识,发现以前太多知识知识略略带过了,比较说Java的线程机制,在Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) ,(PS:以前忽略了). 估计学过Unix开发但是没有细致学习Java的同学们会疑惑了,操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构 建在JVM的基础之上的,意思是Java平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制,而语言或者说

java的守护线程与非守护线程

最近重新研究Java基础知识,发现以前太多知识知识略略带过了,比较说Java的线程机制,在Java中有两类线程:User Thread(用户线程).Daemon Thread(守护线程) ,(PS:以前忽略了). 估计学过Unix开发但是没有细致学习Java的同学们会疑惑了,操作系统里面是没有所谓的守护线程的概念,只有守护进程一说,但是Java语言机制是构建在JVM的基础之上的,意思是Java平台把操作系统的底层给屏蔽起来,所以它可以在它自己的虚拟的平台里面构造出对自己有利的机制,而语言或者说平

学习通过Thread+Handler实现非UI线程更新UI组件

[Android线程机制] 出于性能考虑,Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件 当一个程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理.所以主线程通常又被叫做UI线程 [H

学习通过Thread+Handler实现非UI线程更新UI组件(转)

[Android线程机制] 出于性能考虑,Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件 当一个程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件,用户接触屏幕的事件及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理.所以主线程通常又被叫做UI线程 [H

Java Thread系列(四)线程通信

Java Thread系列(四)线程通信 一.传统通信 public static void main(String[] args) { //volatile实现两个线程间数据可见性 private volatile static List list = new ArrayList(); Thread t1 = new Thread(new Runnable() { // (1) public void run() { try { for(int i = 0; i <10; i++){ list

Java Thread系列(一)线程创建

Java Thread系列(一)线程创建 Java 中创建线程主要有三种方式:继承 Thread.实现 Runnable 接口.使用 ExecutorService.Callable.Future 实现由返回结果的多线程. 一.继承 Thread 类创建线程类 public class MyThread extends Thread { public void run() { for (int i = 0; i < 10000; i++) { System.out.println("线程一