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)

pthreads等待和信号疑问linux

linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)

linux pthreads 上的 gcc 4.7 - 使用 __thread 的重要 thread_local 解决方法(无提升)

如何实现线程互等,线程2等待线程1结束后才继续执行。(可设置标志位) 求源代码

Linux线程及同步