pthread 简要使用指南(二) joinable 与 detached


    pthread_craete()出来的线程,joinable或detached两者必占之一。

    如果是jionale的线程,那么必须使用pthread_join()等待线程结束,否则线程所占用的资源不会得到释放,会造成资源泄露。如果想创建一个线程,但又不想使用pthread_join()等待该线程结束,那么可以创建一个detached的线程。detached状态的线程,在结束的时候,会自动释放该线程所占用的资源。
    detached不需要,也不能使用pthread_join()来等待线程结束。

    另外,一个jionale线程,只能有一个pthread_jion()来等待结束,如果有多个,则只有第一个执行到的有效,其他的都会直接返回,具体错误信息由pthread_join()函数的返回值返回。

    上代码,主要是joinable及detached状态线程的创建,同一线程多个pthread_join(),pthread_join()一个detached线程:


#include 
#include 
#include 
#include 
#include 

// 线程ID
pthread_t       ntid_joinable;
pthread_t       ntid_detached;
// 互斥对象
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int             count;

void printids(const char *s)
{
    pid_t 		pid;
    pthread_t 	tid;

    pid = getpid();
    tid = pthread_self();

    printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid,
        (unsigned int)tid, (unsigned int)tid);
}


// 线程函数
void *thr_joinablefn(void *arg)
{
    printids("new thread thr_joinablefn begin\n");

    // 加锁
    pthread_mutex_lock(&mutex);

    printids("new thread thr_joinablefn:\n");

    int i=0;
    for ( ; i<5; ++i)    
    {
        printf("thr_joinablefn runing %d\n", count++);
        sleep(1);
    }

    // 释放互斥锁
    pthread_mutex_unlock(&mutex);

    return ( (void*)555);
}

// 线程函数
void *thr_detachedfn(void *arg)
{
    printids("new thread thr_detachedfn begin\n");

    // 加锁
    //pthread_mutex_lock(&mutex);

    int err;
    int **ret;
    err = pthread_join(ntid_joinable, (void**)ret);
    if ( err == 0 )
    {
        printf("thr_joinablefn return in thr_detachedfn  %d\n", *ret);
    }
    else
    {
        printf("can't pthread_join ntid_joinable thread in thr_detachedfn :%s\n", strerror(err));
    }

    printids("new thread thr_detachedfn:\n");

    int i=0;
    for ( ; i<10; ++i)    
    {
        printf("thr_detachedfn runing %d\n", count++);
        sleep(1);
    }

    // 释放互斥锁
    //pthread_mutex_unlock(&mutex);

    return ( (void*)666);
}

int main(void)
{
    int err;

    count = 0;
    // 初始化互斥对象
    pthread_mutex_init(&mutex, NULL);

    // 创建joinable线程
    // pthread_craete第二个参数为NULL,则创建默认属性的线程,此时为PTHREAD_CREATE_JOINABLE
    err = pthread_create(&ntid_joinable, NULL, thr_joinablefn, NULL);
    if ( 0 != err )
    {
        printf("can't create ntid_joinable thread:%s\n", strerror(err));
    }

    // 创建detached线程
    pthread_attr_t attr;    
    pthread_attr_init(&attr);
    // 如果下句的 PTHREAD_CREATE_DETACHED 改为 PTHREAD_CREATE_JOINABLE
    // 则该线程与上面创建的线程一样
    pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);   
    err = pthread_create(&ntid_detached, &attr, thr_detachedfn, NULL);
    if ( 0 != err )
    {
        printf("can't create thr_detachedfn thread:%s\n", strerror(err));
    }
    pthread_attr_destroy (&attr);

    int **ret;
    err = pthread_join(ntid_joinable, (void**)ret);
    if ( err == 0 )
    {
        printf("thr_joinablefn return %d\n", *ret);
    }
    else
    {
        printf("can't pthread_join ntid_joinable thread:%s\n", strerror(err));
    }

    err = pthread_join(ntid_detached, (void**)ret);
    if ( err == 0 )
    {
        printf("ntid_detached return %d\n", *ret);
    }
    else
    {
        printf("can't pthread_join ntid_detached thread:%s\n", strerror(err));
    }

    pthread_mutex_destroy(&mutex);

    return 0;
}


运行结果:
new thread thr_joinablefn begin
 pid 2352 tid 4981312 (0x4c0240)
new thread thr_detachedfn begin
 pid 2352 tid 5047072 (0x4d0320)
new thread thr_joinablefn:
 pid 2352 tid 4981312 (0x4c0240)
can't pthread_join ntid_joinable thread in thr_detachedfn :Invalid argument
thr_joinablefn runing 0
new thread thr_detachedfn:
 pid 2352 tid 5047072 (0x4d0320)
thr_detachedfn runing 1
thr_joinablefn runing 2
thr_detachedfn runing 3
thr_joinablefn runing 4
thr_detachedfn runing 5
thr_joinablefn runing 6
thr_detachedfn runing 7
thr_joinablefn runing 8
thr_detachedfn runing 9
thr_joinablefn return 555
thr_detachedfn runing 10
can't pthread_join ntid_detached thread:Invalid argument



你可能感兴趣的:(C/C++)