Linux之線程的創建、等待、終止及分離

線程概念線程是在進程內部運行的(也就是在進程的地址空間內運行的),是進程的一個執行分支。

線程與進程的區別
  1. Linux下線程是在進程的地址空間內運行的,線程擁有進程的一部分資源與代碼,是進程的一個執行分支
  2. 線程是cpu的基本調度單位
  3. 進程是承擔資源分配的基本單位
  4. Linux下進程被稱爲輕量級進程
  5. Linux下無真正意義的線程,線程是用進程模擬實現的

線程之間有共享的資源:
文件描述符表、信號的處理、當前工作目錄、用戶id和組id
線程各自也有私有的資源:
上下文信息(保存各種寄存器的值,和一些上下文的信息)、私有棧空間、線程id、errno變量、信號屏蔽字、調度優先級

創建線程:
使用 int pthread_creat(pthread_t *thread,  const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
參數描述:
thread:線程id,是一個輸出型的參數
attr:線程屬性,在創建時爲NULL
strat_routine:創建線程要去執行的代碼部分
arg:要傳遞給執行代碼部分的參數
返回值:
成功返回0,出錯返回錯誤碼

注意:普通線程運行完成後要進行回收,不然會產生類似於殭屍進程的狀態,從而造成內存泄漏,所以主線程必須等待其他線程,對其進行回收。

線程等待:
使用 int pthread_join(pthread_t thread, void **retval);
//當一個線程在運行中出錯時,整個進程會掛掉,因爲一個線程出錯,操作系統會向發送信號結束其生命,但是操作系統是向pid發送信號,從而導致進程掛掉,進而導致所有線程掛掉。
參數描述:
thread:線程id
retval:輸出型參數,用來獲取線程的退出碼
返回值:
成功返回0,失敗返回對應的錯誤碼

注意:線程要是一直沒有退出,主線程便會一直等待,這種等待方式稱爲阻塞式等待。

線程終止:
線程終止有三種情況:
①正常return;
②void pthread_exit(void *retval);//用於終止線程,類似於進程使用exit()
③int pthread_cancel(pthread_t thread);//線程是可以被取消的,這個函數使一個線程結束掉同一進程的其他線程
成功返回0, 失敗返回其錯誤碼。

注意:在線程中調用exit()會導致進程整體的結束。

線程分離:
線程有兩種狀態,一種爲可結合的,一種爲分離的,一般默認下線程是可結合的。
上面說過,一個線程沒有退出,主線程便一直等待其運行結束,對其資源進行回收,這種狀態就稱爲可結合的。
但是一個線程要是被設置爲分離的,那麼主線程便不會在去等待回收那個線程,這個線程運行結束時會由操作系統對其進行資源回收,而且一個分離線程是不能被其他線程所結束掉的

注意:當一個進程結束時,其有一個分離的線程還未結束,那麼其將會被強制結束,因爲線程的資源都是進程分配給它的,而進程結束時其資源會被操作系統回收,此時線程會被結束掉。當一個線程被設置爲分離時,就不能被等待。

測試代碼:

#include<stdio.h>
#include<pthread.h>

int i = 0;
void *pthread1(void *arg)
{
    while(1)
    {
    sleep(1);
    printf("線程一:running\n");
    if(i++ > 5)
    {
        printf("線程一退出\n");
        break;
    }
    }
}

void *pthread2(void *arg)
{
    while(1)
    {
    sleep(2);
    printf("線程二:running\n");
    }
}

void *pthread3(void *arg)
{
    while(3)
    {
    sleep(2);
    printf("線程三:running\n");
    }
}

int main()
{
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_create(&thread1, NULL, pthread1, NULL);
    pthread_create(&thread2, NULL, pthread2, NULL);
    pthread_create(&thread3, NULL, pthread3, NULL);

    pthread_join(thread1, NULL); //線程1,設置爲被等待
    if(0 == pthread_cancel(thread2))//線程2,被主線取消,一旦運行在這塊,線程2就結束了
    {
         printf("線程二被主線程取消\n");
    }
    if(0 == pthread_detach(thread3)) //線程3,被主線程設置爲可分離狀態
    {
         printf("線程三被主線程設置爲可分離狀態\n");
    }
    sleep(3);//在睡眠的3秒中,只有線程3在運行
}

運行結果:

zhi

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章