• pthread_join与pthread_detach细节问题


    pthread_t    pthr;

    pthread_create(&pthr, NULL, thread_handler, NULL);

    ...

    void* thread_handler(void* arg)

    {

        /* do something */

        pthread_join(pthr, NULL);

    }

     

    上面的代码不好使,pthread_join不能放在pthread调用的handler内,虽然不报错,但是thread无法正常回收,如果多次创建thread,内存会越来越大(另一种形式的内存泄露)。

    正确的做法是在handler外面pthread_join:

     

    pthread_t    pthr;

    pthread_create(&pthr, NULL, thread_handler, NULL);

    pthread_join(pthr, NULL);

    ...

    void* thread_handler(void* arg)

    {

        /* do something */

    }

     

    如果不用pthread_join,改用pthread_detach呢?那最方便,但要注意:pthread_detach最好是放在handler里面第一句。

     

    void* thread_handler(void* arg)

    {

        pthread_detach(pthr);

        /* do something */

    }

     

    如果pthread_create后紧跟pthread_detach,有可能会出错。

     

     

    pthread_detach(pthread_self())
    linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,
    如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。
    若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
    unjoinable 属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
    其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦
     
     
    pthread_self 
    头文件
     #include <pthread.h> 
    函数原型
     pthread_t pthread_self(void);
     函数作用:获得线程自身的ID。pthread_t的类型为unsigned long int,所以在打印的时候要使用%lu方式,否则将产生奇怪的结果。
    功能
     获取当前调用线程的 thread identifier(标识号).
     
     
    近来发现 在线程函数第一行调用 pthread_detach(pthread_self()) 返回值是22不是0,后来在网上找到以下话语:
    linux 线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数 自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源 才会被释放。 
     若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放。
    unjoinable 属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
    在程序运行中检查/proc/ <pid> /maps文件,若看到大概8K左右的很多虚拟内存碎片,基本上可以确认是线程资源泄漏造成的300个线程后pthread_create失败。
     不知是否因为自己,先对要创建的线程做了以下属性设定,
     pthread_attr_init(&attr);
     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
     然后又在线程函数中使用
     pthread_detach(pthread_self());
     两段代码作用有冲突。
    ===============================================================================
    pthread_detach(threadid)和pthread_detach(pthread_self())的区别应该是调用他们的线程不同,没其他区别。
    pthread_detach(threadid) 函数的功能是使线程ID为threadid的线程处于分离状态,一旦线程处于分离状态,该线程终止时底层资源立即被回收;否则终止子线程的状态会一直保存 (占用系统资源)直到主线程调用pthread_join(threadid,NULL)获取线程的退出状态。
     通常是主线程使用pthread_create()创建子线程以后,一般可以调用pthread_detach(threadid)分离刚刚创建的子线程,这里的threadid是指子线程的threadid;如此以来,该子线程止时底层资源立即被回收;
     被创建的子线程也可以自己分离自己,子线程调用pthread_detach(pthread_self())就是分离自己,因为pthread_self()这个函数返回的就是自己本身的线程ID。
     

    Function: pthread_join()

    #include <pthread.h>
    
    int pthread_join(pthread_t thread, void ** status);
    

    If the target thread thread is not detached and there are no other threads joined with the specified thread then the pthread_join() function suspends execution of the current thread and waits for the target thread thread to terminate. Otherwise the results are undefined.

    On a successful call pthread_join() will return 0, and if status is non NULL then status will point to the status argument of pthread_exit(). On failure pthread_join() will return an error number indicating the error.

    ERRORS

    EINVAL The value specified by the thread is not a valid thread.

    ESRCH The specified thread thread is already detached.

    EDEADLK The join would result in a deadlock or the value of thread specifies the calling thread.

    SEE ALSO

    pthread_attr_getdetachstate(), pthread_attr_setdetachstate(), pthread_detach(), pthread_exit()

     个人总结,

    目前不知道上面的是不是正确,但是,ptread_join()会挂起主程序,也就是block,等待join的thread的terminal

  • 相关阅读:
    8 pandas模块,多层索引
    7 numpy 傅里叶,提取图片轮廓
    6 DataFrame处理丢失数据--数据清洗
    5 pandas模块,DataFrame类
    4 pandas模块,Series类
    3 numpy模块
    2 线性代数基础
    1 Ipython、Jupyter 入门
    jdk安装与环境变量配置(一劳永逸)
    对jsp可见域的变量感悟
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/4486567.html
Copyright © 2020-2023  润新知