0

我的程序由多個將數據寫入緩衝區的寫入線程以及從此共享緩衝區讀取數據並將其輸出的讀取線程組成。我需要確保所有寫入線程在讀取線程嘗試讀取數據之前將其數據寫入緩衝區。我的直覺告訴我,我會用信號量來實現它,但它們對我來說真的沒有多大意義。這裏是我的兩個功能:如何在執行某些操作之前確保其他線程已完成

void *search_thread_func(void *threadArgs) 
{ 
printf("\n"); 
//pthread_mutex_lock(&mutex); 
int count = 0; 
int matches = 0; 
int matches_this_line = 0; 
int lines = 0; 
int inputLines = 0; 
int tid; 
int *wbPtr; 
//char *buffer; 
char *sharedBuffer; 
char *writeBuffer; 
char* string; 
string = ((struct st_args*)threadArgs)->string; 
tid = ((struct st_args*)threadArgs)->threadId; 
wbPtr = ((struct st_args*)threadArgs)->wBufPtr; 
//buffer = ((struct st_args*)threadArgs)->threadBuffer; 
sharedBuffer = ((struct st_args*)threadArgs)->sharedBuffer; 
writeBuffer = ((struct st_args*)threadArgs)->writeBuffer; 
//printf("Thread %d\n",(int)tid); 
printf("Searching for %s\n", string); 

//printf("%d\n", (int)sharedBuffer); 
while(sharedBuffer[count] != NULL) 
{ 
    //printf("%c", sharedBuffer[count]); 
    count++; 
    if(sharedBuffer[count] == '\n') 
    { 
     inputLines++; 
    } 
} 

printf("\n"); 
//pthread_mutex_unlock(&mutex); 


char *token; 
char *temp = malloc(count*sizeof(char)); 
memcpy(temp, sharedBuffer, count); 
token = strtok(temp, "\n"); 

while(token != NULL) 
{ 
    printf("%s\n", token); 

    char *q = strstr(token, string); 
    if(q != NULL) 
    { 
     matches_this_line++; 
     lines++; 

     for(char *r = q; r != NULL; r= strstr(r+strlen(string), string)) 
     { 
      matches++; 
     } 
     pthread_mutex_lock(&mutex); 
     for(int j = 0; j < strlen(token); j++) 
     { 
      writeBuffer[*wbPtr] = token[j]; 
      *wbPtr = *wbPtr + 1;  
     } 
     writeBuffer[*wbPtr] = '\n'; 
     *wbPtr = *wbPtr + 1; 
     pthread_mutex_unlock(&mutex); 

    } 

    token = strtok(NULL, "\n"); 
} 

printf("lines %d, matches %d\n", lines, matches); 

printBuffer(writeBuffer, *wbPtr); 

free(temp); 
printf("\n"); 
} 

void *write_thread_func(void *threadArgs) 
{ 
printf("write func\n"); 
char *writeBuffer; 
int * wbPtr; 
FILE* wFP; 
writeBuffer = ((struct wt_args*)threadArgs)->writeBuffer; 
wFP = ((struct wt_args*)threadArgs)->wFP; 
wbPtr = ((struct st_args*)threadArgs)->wBufPtr; 
printf("wbPtr = %d\n", wbPtr); 
printf("*wbPtr = %d\n", *wbPtr); 
//printf("wb loc = %d\n", writeBuffer); 

} 

基本上搜索線程搜索一些數據和其他數據寫入緩衝區。我還沒有實現write_thread_func從緩衝區讀取數據,但這很簡單。我知道互斥鎖如何工作,但我認爲這不會起作用,因爲我需要確保write_thread_func最後執行,或者等到search_thread_funcs完成寫入緩衝區爲止。

回答

1

如果數據的使用者也是線程的創建者,它可以簡單地將它們全部都確定完成。否則,執行此操作的規範方法是使用數據結構中的互斥鎖和條件變量,以及基於數據結構內容的「數據完整」謂詞。消費者會等待條件變量,並且產生數據的線程在更新斷言所依賴的數據之後發出信號,同時持有互斥量。有一些方法可以用信號量實現同樣的事情(例如讓每個生產者發佈一次信號量,並且消費者等待N次,其中N是生產者的數量),但是這種類型的設計需要消費者知道更多的細節(如有多少生產者)可能不是它的業務知道。

+0

此外,信號量是系統範圍的,而不是特定於某個進程,所以如果運行了多個程序副本,則可能會遇到麻煩。 – user3303729

+0

@ user3303729:不,這只是一個問題,如果(1)您使用sysv信號量或命名的POSIX信號量,並且(2)您無法爲它們生成唯一的名稱。使用匿名進程本地POSIX信號量('sem_init')是首選方法。 –

相關問題