線程分離

pthread_detach函數

實現線程分離linux

       int pthread_detach(pthread_t thread);      成功:0;失敗:錯誤號ubuntu

       線程分離狀態:指定該狀態,線程主動與主控線程斷開關係。線程結束後,其退出狀態不禁其餘線程獲取,而直接本身自動釋放。網絡、多線程服務器經常使用。服務器

       進程如有該機制,將不會產生殭屍進程。殭屍進程的產生主要因爲進程死後,大部分資源被釋放,一點殘留資源仍存於系統中,致使內核認爲該進程仍存在。網絡

       也可以使用 pthread_create函數參2(線程屬性)來設置線程分離。多線程

【練習】:使用pthread_detach函數實現線程分離                                                                      【pthrd_detach.c】函數

通常狀況下,線程終止後,其終止狀態一直保留到其它線程調用pthread_join獲取它的狀態爲止。可是線程也能夠被置爲detach狀態,這樣的線程一旦終止就馬上回收它佔用的全部資源,而不保留終止狀態。不能對一個已經處於detach狀態的線程調用pthread_join,這樣的調用將返回EINVAL錯誤。也就是說,若是已經對一個線程調用了pthread_detach就不能再調用pthread_join了。spa

/***
detach.c
***/
#include<unistd.h>
#include<string.h>
#include<pthread.h>
#include<stdio.h>

void *tfn(void *arg)
{
    int n = 3;
    while(n--)
    {
        printf("thread count %d\n",n);
        sleep(1);
    }
    pthread_exit((void*)1);
}

int main()
{
    pthread_t tid;
    void* tret;
    int err;

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
    pthread_create(&tid,&attr,tfn,NULL);

    while(1)
    {
        err = pthread_join(tid,&tret);
        printf("------------------- err = %d\n",err);
        if(0 != err)
        {
            fprintf(stderr,"thread_join error : %s\n",strerror(err));
        }
        else
        {
            fprintf(stderr,"thread exit code %d\n",(int)tret);
        }
        sleep(1);
    }

    return 0;
}

運行結果:線程

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./detachcode

------------------- err = 22blog

thread_join error : Invalid argument

thread count 2

------------------- err = 22

thread_join error : Invalid argument

thread count 1

------------------- err = 22

thread_join error : Invalid argument

thread count 0

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

------------------- err = 22

thread_join error : Invalid argument

^C

pthread_cancel函數

殺死(取消)線程                  其做用,對應進程中 kill() 函數。

       int pthread_cancel(pthread_t thread); 成功:0;失敗:錯誤號

       【注意】:線程的取消並非實時的,而有必定的延時。須要等待線程到達某個取消點(檢查點)。

       相似於玩遊戲存檔,必須到達指定的場所(存檔點,如:客棧、倉庫、城裏等)才能存儲進度。殺死線程也不是馬上就能完成,必需要到達取消點。

       取消點:是線程檢查是否被取消,並按請求進行動做的一個位置。一般是一些系統調用creat,open,pause,close,read,write..... 執行命令man 7 pthreads能夠查看具有這些取消點的系統調用列表。也可參閱 APUE.12.7 取消選項小節。

可粗略認爲一個系統調用(進入內核)即爲一個取消點。如線程中沒有取消點,能夠經過調用pthreestcancel函數自行設置一個取消點。

被取消的線程,   退出值定義在Linux的pthread庫中。常數PTHREAD_CANCELED的值是-1。可在頭文件pthread.h中找到它的定義:#define PTHREAD_CANCELED ((void *) -1)。所以當咱們對一個已經被取消的線程使用pthread_join回收時,獲得的返回值爲-1。

【練習】:終止線程的三種方法。注意「取消點」的概念。                                                              【pthrd_endof3.c】

終止線程方式

總結:終止某個線程而不終止整個進程,有三種方法:

  1. 從線程主函數return。這種方法對主控線程不適用,從main函數return至關於調用exit。
  2. 一個線程能夠調用pthread_cancel終止同一進程中的另外一個線程。
  3. 線程能夠調用pthread_exit終止本身
/***
pthread_endof3.c
***/

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


void *tfn1(void *arg)
{
    printf("thread 1 returning\n");

    return (void *)111; 
}

void *tfn2(void *arg)
{
    printf("thread 2 exiting\n");
    pthread_exit((void *)222);
}

void *tfn3(void *arg)
{
    while (1) {
        //printf("thread 3: I'm going to die in 3 seconds ...\n");
        //sleep(1);

        pthread_testcancel();    //本身添加取消點*/
    }

    return (void *)666;
}

int main(void)
{
    pthread_t tid;
    void *tret = NULL;

    pthread_create(&tid, NULL, tfn1, NULL);
    pthread_join(tid, &tret);
    printf("thread 1 exit code = %d\n\n", (int)tret);

    pthread_create(&tid, NULL, tfn2, NULL);
    pthread_join(tid, &tret);
    printf("thread 2 exit code = %d\n\n", (int)tret);

    pthread_create(&tid, NULL, tfn3, NULL);
    sleep(3);
    pthread_cancel(tid);
    pthread_join(tid, &tret);
    printf("thread 3 exit code = %d\n", (int)tret);

    return 0;
}

ubuntu1604@ubuntu:~/wangqinghe/linux/20190819$ ./pthread_endof3

thread 1 returning

thread 1 exit code = 111

 

thread 2 exiting

thread 2 exit code = 222

 

thread 3 exit code = -1

相關文章
相關標籤/搜索