2012年9月25日 星期二

[C/C++] 終止 thread 的執行

程式寫到一定的等級之後,就會開始用同一程式卻同時要完成多個事情,又或者是執行向系統要資源的工作。這些情況都會需要使用thread進行多工處理。常見的例子:socket programworker & manager 類型的大型程式...等等。

其中有時候會面臨一個問題,thread掛掉了怎麼辦?


查了一些相關文件,都指出使用 pthread_create() + pthread_cancel() 的組合可以解決這個問題。然而實際上,普通的作法大多會無效。原因在於雖然 manager thread 呼叫 pthread_cancel() 會把終止信號傳遞給 worker thread,但是 c 標準函式庫卻規範預設狀況 thread 接受信號並且處於 cancellation point (有一種說法是閒置狀態 Ex: sleep(n) )時,此 cancel 信號才會作用。既然有所謂的預設狀況,表示說 c 函式庫允許 programmer 設置想要的 cancel 接受信號的反應方式。

以下程式運行環境為 windows XP,dev-c++ 加裝 pthread_win32 lib。
編譯選項 linker 加上 -lpthreadGC2


[ Code ]  <, > 符號需取代掉)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct thread_parameters
{
int thread_id;
};

void *threadManager(void *get_param);
void *threadRoutine(void *args);
pthread_t thread[5];

int main(int argc, char *argv[])
{
int error_msg;
int count = 0;
struct thread_parameters t_param[5];
for (count=0; count<2; count++)
{
t_param[count].thread_id = count;
error_msg = pthread_create(&thread[count], NULL, threadRoutine, &t_param[count]);
}

  // start a thread manager
error_msg = pthread_create(&thread[4], NULL, threadManager, &t_param[4]);

  for (count=0; count<2; count++)
{
error_msg = pthread_join(thread[count], NULL);
printf("thread %d terminate\n", count);
}
printf("END\n");
system("pause");
return 0;
}

void *threadRoutine(void *get_param)
{
     
struct thread_parameters *t_param;
t_param = get_param;

    // enable cancel thread 
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,   NULL);   
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,   NULL);   

  if(t_param->thread_id==0){
while(1){
            printf("Thread0...\n");
            //sleep(1000);
        }
    }
else if(t_param->thread_id==1){
while(1){
            printf("Thread1...\n");
           // sleep(1000);
        }
    }
return ;
}

void *threadManager(void *get_param)
{
// wait a time to terminal routine thread
//sleep(1000); // for dev-c++
sleep(1); // for linux

  pthread_cancel(thread[0]);
pthread_cancel(thread[1]);
printf("END of threadMnager\n");
return ;
}



[ Reference ]
#1 c++ - kill thread in thread

沒有留言: