zoukankan      html  css  js  c++  java
  • 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是否为守护线程概念的(最多只有守护进程概念);但我们可以在main线程的main()方法最后加入 join() 其他创建的所有子线程的方法,来模拟其他子线程是非守护线程的行为:也就是让主线程等待其他子线程执行完,整个进程才退出

    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

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

  • 相关阅读:
    Atitit 函数调用的原理与本质attilax总结 stdcall cdecl区别
    Atitit 图像处理 halcon类库的使用  范例边缘检测 attilax总结
    互联网创业原则与创业模式attilax大总结
    Atitit SeedFilling种子填充算法attilax总结
    Atitit 软件体系的进化,是否需要一个处理中心
    Atitit 获取剪贴板内容
    Atitit 架构的原则attilax总结
    Atitit Atitit 零食erp数据管理世界著名零食系列数据.docx世界著名零食
    Atitit 个人信息数据文档知识分类
    Atitti python2.7安装 numpy attilax总结
  • 原文地址:https://www.cnblogs.com/cyy12/p/12216411.html
Copyright © 2011-2022 走看看