views:

121

answers:

3

There's a weird behavior in my threads:

void * foo(void * nic){
    printf("foo");
}
void * threadF(void * pointer){
    printf("1\n");
    pthread_t threadT;
    pthread_attr_t attr;
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&threadT,NULL,&foo,(void*)NULL);
    printf("2\n");
    while (!feof(stdin)){
        int id, in, out;
        fscanf(stdin,"%d:%d:%d",&id,&in,&out);
    }
}

int main(){
    pthread_attr_t attr;
    pthread_attr_init (&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_t threadT;
    pthread_create(&vlaknoVstupu,&attr,&threadF,(void*)&data);
    pthread_join(threadT,NULL);
    pthread_attr_destroy (&attr);
}
// I skipped irelevant parts of code...

the thing is that sometimes the output is 12foo, but usually just 12. Then the function waits for input. I would expect it to be always 12foo. Do anybody know why are my expectations wrong?

Edit: when I type some input like 1:1:1, which results in going through the while cycle again, there is always the foo output.

A: 

Since there is no join call for thread foo, the program is probably ending before it runs.

Mark Wilkins
the state when I'm reading the output is that the process is still running and waiting for input.`while(!feof(stdin)){...}`Adding a line with join after the `while` still doesn't change anything.
coubeatczech
+2  A: 

Printf does not have a thread guarantee. You shouldn't just call two functions on the same thing from different threads unless it's explicitly guaranteed to be safe, either by the writer or because you wrote it yourself.

What you should do is store a buffer of string pointers, and use atomic operations to insert strings into this buffer, then printf all of them every so often, free the memory, set to null, or just use a lock if it's ok to make the child threads wait on the printf call.

DeadMG
thanks, this helped.
coubeatczech
+1  A: 

What happens is that (on most implementations) stdin and stdout are tied together in one practical buffer. This is to allow something like:

printf("Input: ");
scanf("%d", &integer);

to work nicely, the inputted characters will appear after the printf text.

As soon as your scanf will grab the stdin, this will 'lock' that buffer, also preventing the stdout of your other thread to flush its data to the screen. Note that 'lock'. Does not necessarily mean real thread locks.

If you'd call the program from console, input something like 1:2:3, and hit enter, you'd see that foo will be displayed at the end.

KillianDS