如何在执行某些操作之前确保其他线程已完成

时间:2014-03-06 23:28:46

标签: c multithreading synchronization pthreads inter-process-communicat

我的程序包含许多将数据写入缓冲区的写线程,以及从该共享缓冲区读取数据并输出数据的读取线程。我需要确保所有写入线程在读取线程尝试从中读取数据之前已将其数据写入缓冲区。我的直觉告诉我,我会用信号量来实现它,但它们对我来说真的没有多大意义。这是我的两个功能:

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 个答案:

答案 0 :(得分:1)

如果数据的使用者也是处理它的线程的创建者,那么它可以简单地pthread_join全部并且确保它们已经完成。否则,执行此操作的规范方法是使用数据结构中的互斥锁和条件变量,以及基于数据结构内容的“数据完整”谓词。消费者会等待条件变量,生成数据的线程会在更新谓词所依赖的数据后发出信号。

有多种方法可以用信号量实现相同的功能(例如,让每个生产者发布信号量一次,消费者等待N次,其中N是生产者的数量),但这种类型设计要求您的消费者了解更多可能无法了解其业务的详细信息(例如,有多少生产商)。