2010-06-06 128 views
-2

承擔創建通過在pthread_create 3個工作線程,多任務處理如何使調用無限循環功能

在這些工作線程例行

後工作線程增益控制,每次調用哪個沒有回做計數一個簡單的無限循環功能

如何在調用無限循環函數之後使工作線程增益控制並保存用於在工作線程中再次調用的無限循環函數的上下文?

+3

這個問題真的很混亂。你能說清楚,根據我的理解,如果你想讓線程恢復控制,你應該等待一些共享變量(信號量等) – 2010-06-06 08:07:38

回答

0

讓我換句話來看看我是否理解了這個問題。

您有一個主線程,它產生3個工作線程,每個工作線程執行長時間運行(無限)工作。

在您希望中斷處理的某個點上,保存所有線程的狀態以恢復以後停止的位置。

我認爲這樣做的最好方法是組織您的線程在事務綁定塊中工作。重新啓動時,檢查上次完成的事務,然後從那裏開始。

但是由於我懷疑這是低級別線程管道中的家庭作業分配,我可能會建議一個共享布爾值,在您每次通過循環退出並存儲狀態之後選中該值。另一種方法是「殺死」線程並捕獲異常並存儲狀態。最後一個選項是混亂的。

+0

如果使用定時器來中斷無限循環功能並通過從函數到工作線程的映射返回到工作線程? – user353573 2010-06-06 10:48:18

+0

可以通過pthread_cleanup_push保存無限循環函數的上下文(例如,我們停止的行,函數中的變量)嗎? – user353573 2010-06-06 10:50:53

+0

我現在很困惑。如果啓動該線程,OS將負責劃分線程之間的時間,並且不需要關注上下文。它自己運行。線程也不會「返回」:它們在完成時停止。 正如在下面的帖子中所說的,輪詢循環是糟糕的設計,並且最好讓線程在等待更多工作時阻塞。使用阻塞隊列,讀取文件或FIFO,套接字,... – 2010-06-06 14:43:54

0

想做一個線程池的作用,呼籲無限循環功能後,每個工作線程可以改變其他任務(其他無限循環功能)運行

例如3個工作線程可以運行4個任務(無限循環功能)

#ifndef JOB_CPP 
#define JOB_CPP 

#include "job.h" 

#define NUM_OF_TASKS 4 
#define NUM_OF_WORKERS 3 
    void (* job_queue[NUM_OF_TASKS])(void*); 
    void (* fp[NUM_OF_WORKERS])(void*); // original running job 
    int running_task[NUM_OF_WORKERS]; 
    int idle[NUM_OF_TASKS]; 
    int last_running_task[NUM_OF_WORKERS]; 
    int no_of_tasks_running[NUM_OF_WORKERS]; 
    my_struct_t data = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0}; 

void func1(void *arg) 
{ 
    int count = 0; 
    int status; 
    while(true) 
    { 
     //if((count % 100) == 0) 
     //printf("func1 run %d\n", count); 
     count = count + 1; 
     //status = pthread_cond_signal(&data.cv); 
    } 
} 
void func2(void *arg) 
{ 
    int count = 0; 
    int status; 
    while(true) 
    { 
     //printf("func2 run %d\n", count); 
     count = count + 1; 
     //status = pthread_cond_signal(&data.cv); 
    } 
} 
void func3(void *arg) 
{ int count = 0; 
    int status; 
    while(true) 
    { 
     //printf("func3 run %d\n", count); 
     count = count + 1; 
     //status = pthread_cond_signal(&data.cv); 
    } 
} 
void func4(void *arg) 
{ int count = 0; 
    int status; 
    while(true) 
    { 
     //printf("func4 run %d\n", count); 
     count = count + 1; 
     //status = pthread_cond_signal(&data.done); 
    } 
} 

void jobinit() 
{ 
    for(int i=0; i<NUM_OF_TASKS; i++) 
    { 
     job_queue[i] = NULL; 
     idle[i] = 0; 
    } 
    for(int i=0; i<NUM_OF_WORKERS; i++) 
    { 
     fp[i] = NULL; 
     running_task[i] = 0; 
     last_running_task[i] = 0; 
     no_of_tasks_running[i] = 0; 
    } 
    jobadd(func1); 
    jobadd(func2); 
    jobadd(func3); 
    jobadd(func4); 
    jobrun(); 
} 
void jobadd(void (*job)(void*)) 
{ 
    for(int i=0; i<4; i++) 
    { 
     if(job_queue[i] == NULL) 
     { 
      job_queue[i] = job; 
      return; 
     } 
    } 
} 
void* workserver(void *arg); 
void* workserver(void *arg) 
{ 
    int status, timedout; 

    struct timespec timeout; 

    status = pthread_mutex_lock(&data.mutex); 
    while(true) 
    { 
     timedout = 0; 
     clock_gettime(CLOCK_REALTIME, &timeout); 
     timeout.tv_sec += 2; 

     sleep(1); 
     //void (* clean)(void*); 

     status = pthread_cond_timedwait(&data.cv, &data.mutex, &timeout); 
     if(status == ETIMEDOUT){ 
      printf("worker wait timed out %d\n", (int)arg); 
      timedout = 1; 
     }else if(status != 0){ 
      printf("worker wait failed %d\n", (int)arg); 
      status = pthread_mutex_unlock(&data.mutex); 
      return NULL; 
     } 
     printf("workserver number: %d\n", (int)arg); 

     status = pthread_mutex_unlock(&data.mutex);  

     printf("function run %d\n", (int)arg); 
     (* job_queue[(int)arg])(NULL); 

     printf("cond wait start %d\n", (int)arg); 
     status = pthread_cond_wait(&data.done, &data.mutex); 
     printf("cond wait end\n"); 

     status = pthread_mutex_lock(&data.mutex); 
    } 
} 
void jobrun() 
{ 
    for(int i=0; i<3; i++) {idle[i] = 0;} 
    pthread_t r1_threadid[3]; 

    for(int i=0; i<3; i++) 
    { 
     pthread_create(&r1_threadid[i], NULL, workserver, (void*)i); 
    } 

    int status; 
    struct timespec timeout; 

    timeout.tv_sec = time (NULL) + 2; 
    timeout.tv_nsec = 0; 

    while(true) 
    { 
    status = pthread_mutex_lock(&data.mutex); 
    while(data.value == 0) 
    { 
     status = pthread_cond_timedwait(&data.cond, &data.mutex, &timeout); 
    } 
    if(data.value != 0) 
    { 
     //printf("condition was signaled\n"); 
     data.value = 0; 
    } 
    status = pthread_mutex_unlock(&data.mutex); 
    if(status != 0) 
     printf("unlock mutex error"); 
    } 
} 
#endif 
+0

你真的需要更多地關注你的帖子的格式。這實際上難以辨認。 (內容與格式幾乎不可理解。 我懷疑你想要的是找到一些庫,它提供了一個「生產者/消費者」隊列,以便你的工作者線程都可以在這個庫上進行阻塞讀取調用(作爲消費者)。然後,您的主線程將工作分派到該隊列中(或者可以從工作者處饋送:「反饋」)。阻塞呼叫會比一些繁忙的等待輪詢「無限循環」更好。退出事件可以被送入隊列以終止線程。 – 2010-06-06 08:41:02

+0

對不起,我已經在網頁中使用了添加示例代碼功能,但是在將代碼複製到網頁後,它仍然弄得一團糟,不知道我出錯的地方 – user353573 2010-06-06 09:11:31

0

我想你應該澄清你的問題。

如果每個工作者線程調用一個無限循環,那麼我想你的主線程將不得不在每個線程上調用pthread_cancel()。從我收集的信息可能需要調用其他pthread_*()函數來設置目標線程的「可取消性」。

當然這個建議引發了問題。最好的辦法是防止那些無限循環。編寫代碼以使其具有退出條件......以便工作受到某種輸入的限制或具有某種事件處理。

+0

在調用無限循環函數之後,主線程工作線程)取消現有的運行功能 我的意思是當一個線程運行一個任務(無限循環函數)以及工作線程如何使任務在特定點停止並保存上下文並運行另一個任務,然後返回運行先前的任務再次 – user353573 2010-06-06 09:09:08