Linux:回收循環建立的多個線程

上午我說了循環建立多個線程,因爲進程與線程是如此的類似,進程咱們知道要回收,那麼線程也天然要回收啦。咱們接着看控制原語: 多線程

線程與共享 函數

線程間共享全局變量! spa

牢記】:線程默認共享數據段、代碼段等地址空間,經常使用的是全局變量。而進程不共享全局變量,只能藉助mmap。 線程

pthread_exit函數 指針

將單個線程退出 進程

    void pthread_exit(void *retval);    參數:retval表示線程退出狀態,一般傳NULL 內存

思考:使用exit將指定線程退出,能夠嗎?                                            【pthrd_exit.c】 string

    結論:線程中,禁止使用exit函數,會致使進程內全部線程所有退出。 it

    在不添加sleep控制輸出順序的狀況下。pthread_create在循環中,幾乎瞬間建立5個線程,但只有第1個線程有機會輸出(或者第2個也有,也可能沒有,取決於內核調度)若是第3個線程執行了exit,將整個進程退出了,因此所有線程退出了。 io

    因此,多線程環境中,應儘可能少用,或者不使用exit函數,取而代之使用pthread_exit函數,將單個線程退出。任何線程裏exit致使進程退出,其餘線程未工做結束,主控線程退出時不能return或exit。

另注意,pthread_exit或者return返回的指針所指向的內存單元必須是全局的或者是用malloc分配的,不能在線程函數的棧上分配,由於當其它線程獲得這個返回指針時線程函數已經退出了。

總結exit、return、pthread_exit各自退出效果。

return:返回到調用者那裏去。

pthread_exit():將調用該函數的線程退出

exit: 將進程退出。

pthread_join函數

阻塞等待線程退出,獲取線程退出狀態        其做用,對應進程中 waitpid() 函數。

    int pthread_join(pthread_t thread, void **retval); 成功:0;失敗:錯誤號

    參數:thread:線程ID (【注意】:不是指針);retval:存儲線程結束狀態。

    對比記憶:

        進程中:main返回值、exit參數-->int;等待子進程結束 wait 函數參數-->int *

        線程中:線程主函數返回值、pthread_exit-->void *;等待線程結束 pthread_join 函數參數-->void **

參數 retval 非空用法。

調用該函數的線程將掛起等待,直到id爲thread的線程終止。thread線程以不一樣的方法終止,經過pthread_join獲得的終止狀態是不一樣的,總結以下:

  1. 若是thread線程經過return返回,retval所指向的單元裏存放的是thread線程函數的返回值。
  2. 若是thread線程被別的線程調用pthread_cancel異常終止掉,retval所指向的單元裏存放的是常數PTHREAD_CANCELED。
  3. 若是thread線程是本身調用pthread_exit終止的,retval所指向的單元存放的是傳給pthread_exit的參數。
  4. 若是對thread線程的終止狀態不感興趣,能夠傳NULL給retval參數。

上面說的很清楚啦,因此回收線程的代碼實現也很簡單啦:

#include <stdio.h>

#include <pthread.h>

#include <string.h>

#include <stdlib.h>

typedef struct {

    int x;

    int y;

    char p[128];

}my_func;

void *func(void*arg)

{

    my_func *mf = (my_func*)malloc(sizeof(my_func));

    int i = (int)arg;

    mf->x = i;

    mf->y = i * i;

    strcpy(mf->p, "my lover is dandan.");

    printf("我是第%d個線程,個人線程ID是%lu\n", i + 1, pthread_self());

    pthread_exit(mf);

}

int main(void)

{

    pthread_t pth[5];

    my_func *mf;//這裏是指針啊,是指針啊,不是一個實例啊

    for (int i = 0; i != 5; i++)

    {

        pthread_create((pth + i), NULL, func, (void*)i);

        if (!pthread_join(pth[i], (void**)&mf))

        {

            printf("回收線程成功!線程ID:%lu。\n", pth[i]);

            printf("my_func中的x = %d, y = %d, p = %s。\n\n", mf->x, mf->y, mf->p);

        }

        else

            printf("失敗!\n");

    }

    return 0;

}

主要是各類轉化要注意,還有的是:my_func *mf;//這裏是指針啊,是指針啊,不是一個實例啊         這句話很重要啊,我就說爲何個人mf輸出像是沒有通過初始化和賦值操做的。還有,不用擔憂我沒有free而形成內存泄漏,pthread_exit函數是把這些考慮好了的。還有個人pthread_exit是傳參數進去的,主要是想獲取一下線程退出的狀態。是否是和wait很相似?

相關文章
相關標籤/搜索