Linux 進程與線程二(等待--分離--取消線程)


int pthread_join(pthread_t thr,void **thr_return);
pthread_join函數用於掛起當前線程,直至th指定的線程終止為止。
如果另一個線程返回值不是NULL,則保存在thr_return地址中。
一個線程所使用的內存資源在應用pthread_join調用之前不會被重新分配,所以對於每個線程必須調用一次pthread_join函數(被分離線程除外)。
其他線程不能對同一線程再應用pthread_join調用。
pthread_join函數成功返回0,失敗返回錯誤碼
參數thr_return就是線程th的返回值
這個函數的應用場景一般是在控制線程中調用,用來等待其他線程返回,跟進程中wait()函數類似。
一個線程退出后(在控制線程不退出的情況下),該線程所使用的內存資源並沒有被釋放,需要調用pthread_join()函數釋放
//pthread_join的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
    int *p = (int *) malloc(sizeof(int));
    if (p == NULL)
    {
        printf("分配內存失敗!\n");
        return NULL;
    }
    *p = 5;
    return p;
}

void * Myfunc2(void *arg)
{
    int *p = (int *) malloc(sizeof(int));
    if (p == NULL)
    {
        printf("分配內存失敗!\n");
        return NULL;
    }
    *p = 10;
    pthread_exit(p);
}

int main(int arg, char *args[])
{
    pthread_t thr1, thr2;
    if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    if (pthread_create(&thr2, NULL, Myfunc2, NULL) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    int *returnnum1 = NULL;
    int *returnnum2 = NULL;
    /*
     pthread_join()函數主要的量大的功能
     1.將控制線程掛起,等待指定的線程返回
     2.釋放指定的線程的內存資源(線程正常退出並沒有釋放自身占用的資源,除非進程退出)
     */
    pthread_join(thr1, (void **) &returnnum1);
    if (returnnum1 != NULL)
    {
        printf("thr1 return number is %d\n", *returnnum1);
    }

    pthread_join(thr2, (void **) &returnnum2);
    if (returnnum2 != NULL)
    {
        printf("thr2 return number is %d\n", *returnnum2);
    }
    return 0;
}

 

int pthread_detach(pthread_t th);
pthread_detach函數使線程處於被分離狀態。
對於被分離狀態的線程,同時對線程的返回值不感興趣,可以設置這個線程被分離狀態,讓系統在線程退出的時候自動回收它所占用的資源。
一個線程不能自己調用pthread_detach改變自己被分離狀態,只能由其他線程調用pthread_detach。
一旦線程成為可分離線程之后,就不能再使用pthread_joisn()函數了,因為沒有意義。
pthread_detach()成功返回0,失敗返回錯誤碼。
線程處於被分離狀態下,控制線程退出,被分離線程也會退出,被分離線程只是不需要使用pthread_join函數來釋放內存資源。

可分離線程的使用場景
1.主線程不需要等待子線程
2.主線程不關心子線程的返回碼
//pthread_detach的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
    while(1)
    {
        printf("fly with me \n");
        sleep(1);
    }
    return NULL;
}

int main(int arg, char *args[])
{
    pthread_t thr1;
    if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    pthread_detach(thr1);
    sleep(3);
    printf("main end \n");
    return 0;
}

 

int pthread_cancel(pthread_t th);
pthread_cancel函數允許一個線程取消th指定的另一個線程
函數成功返回0,失敗返回非0.
//pthread_join的使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>
#include <errno.h>
#include <pthread.h>

void * Myfunc(void *arg)
{
    while (1)
    {
        printf("fly with me \n");
        sleep(1);
    }
    int *p = malloc(sizeof(int));
    *p = 7;
    return p;
}

void * Myfunc2(void *arg)
{
    if(arg==NULL)
    {
        printf("param is not allow NULL!\n");
        return NULL;
    }
    sleep(5);
    pthread_t thr;
    thr=*(pthread_t *)arg;
    pthread_cancel(thr);
    int *p = malloc(sizeof(int));
    *p = 8;
    return p;
}

int main(int arg, char *args[])
{
    pthread_t thr1, thr2;
    if (pthread_create(&thr1, NULL, Myfunc, NULL) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    if (pthread_create(&thr2, NULL, Myfunc2, &thr1) != 0)
    {
        printf("create thread is failed ! error message :%s\n",
                strerror(errno));
        return -1;
    }
    int *numx1 = NULL;
    int *numx2 = NULL;
    pthread_join(thr1, (void **) &numx1);
    pthread_join(thr2, (void **) &numx2);
    /*
     程序報錯,線程thr1在執行中被強制取消,返回值numx1並不是NULL
     */
    /*
    if (numx1 != NULL)
    {
        printf("thr1 return code is %d\n", *numx1);
        free(numx1);
        numx1 = NULL;
    }
    */
    if (numx2 != NULL)
    {
        printf("thr2 return code is %d\n", *numx2);
        free(numx2);
        numx2 = NULL;
    }
    printf("main end \n");
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM