Question

My program is comprised of a number of writing threads who write data into a buffer, and a reading thread who reads the data from this shared buffer and outputs it. I need to make sure that all of the write threads have written their data into the buffer before the read thread attempts to read from it. My intuition tells me I would implement this using semaphores, but they really don't make much sense to me. Here are my two functions:

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);

}

Basically the search threads search through some data and write other data to the buffer. I haven't implemented the write_thread_func's reading from the buffer yet, but thats pretty trivial. I understand how mutex locks work, but I don't think that would work here because I need to ensure that write_thread_func executes last, or waits until the search_thread_funcs finish writing to the buffer.

No correct solution

OTHER TIPS

If the consumer of the data was also the creator of the threads working on it, it can simply pthread_join them all and be sure they are finished. Otherwise, the canonical way to do this would be with a mutex and condition variable in the data structure, and a "data is complete" predicate based on the contents of the data structure. The consumer would wait on the condition variable, and the threads producing the data would signal, after updating the data on which the predicate depends while holding the mutex.

There are ways to achieve the same thing with semaphores (e.g. have each producer post the semaphore once, and the consumer wait N times, where N is the number of producers), but this type of design requires your consumer to know more details (like how many producers there are) that might not be its business to know.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top