Wrong Output using Mutex and Pthread Library

The purpose of the below program is to learn Mutex and Pthread library. The main() creates three thread. (thread 1, 2 & 3). Each thread one-by-one sequentially, reads one character per file (different file) and stores into the global constant. Example thread 1 reads character 'a' from file1, then wait for thread 2 & 3 to the same (i.e. read 'b' and 'c' from file2 and file3 respective). Once the reading is finished, we want the main to print the global constant to file.out

I have attempted to program the same but getting incorrect output.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>

char glob_var, strtemp[1024];
pthread_mutex_t lock;
int cnt = 0;
char inp[3][10] = {"file-1.in", "file-2.in", "file-3.in"};

void * thread_func(void * arg);

void * thread_func(void * arg)
{
    FILE *fp;
    char * argu = (char *)arg;
    fp = fopen(argu, "r");
    while (1) {
        pthread_mutex_lock(&lock);
        glob_var = fgetc(fp);
        if(feof(fp))
        { 
            pthread_mutex_unlock(&lock);
            break ;
        }
        if (glob_var != '\n')
            strtemp[cnt++] = glob_var;
        pthread_mutex_unlock(&lock);
    }
    fclose(fp);

    return (void *)0;
}

int main(void)
{
    FILE * fpout;
    pthread_t threads[3];
    int i = 0;

    fpout = fopen("file.out", "w");

    for (i = 0; i < 3; i++)
        pthread_create(&threads[i], NULL, thread_func, (void *)inp[i]);

    for (i = 0; i < 3; i++)
        pthread_join(threads[i], NULL);

    strtemp[cnt] = '\0';
    cnt = 0;

    while(1) {
        glob_var = strtemp[cnt++];
        fprintf(fpout, "%c\n", glob_var);
        if (strtemp[cnt] == '\0') {
            break;
        }
    }
    fclose(fpout);

    return 0;
}

Input File

File1 File2 File3
a     u     t
o     .     #
e     p     a
i     r     m
e     n     $

Output File

From Above Code         Desired Output
t                       a
#                       u
r                       t
a                       o
m                       .
!                       #
$                       e
s                       p
m                       a
u                       i
.                       r
p                       m
r                       e
n                       n

Answers


Your mutex here only makes sure no more than one thread accesses your global variables at the same time. It doesn't give you any guarantees on the order in which the threads are scheduled. For what you want to do, a mutex is the wrong synchronization primitive because it is designed for exactly that: exclude other threads from accessing the same resource at the same time.

You want to explicitly allow a specific thread after another thread. This can be done using semaphores. You would need one per thread. So, declare a second sem_t array globally with 3 entries, initialize the first to 1, the others to 0. Then, pass just a thread number (0 - 2) to your threads and do something like:

int next = num + 1;
if (next > 2) next = 0;
sem_wait(sems[num]);
/* your code, accessing inp[num] */
sem_post(sems[next]);

Need Your Help

SSRS - nested IIF in the expression

reporting-services ssrs-2008 iif-function

=iif((Fields!Company_OEM.Value = "Channel") AND (Parameters!paramCompanyOEM.Count &lt; 2), "None", iif(Not(Fields!Company_OEM="Channel"), Count(Fields!TS_ISSUEID.Value), "None"))