Program flow during topic creation

I am new to streams.

I wrote a sample program to create a stream.

#include<stdio.h> #include<stdlib.h> #include<limits.h> #include<string.h> #include<pthread.h> void * func(void * temp) { printf("inside function\n"); return NULL; } int main() { pthread_t pt1; printf("creating thread\n"); pthread_create(&pt1,NULL,&func,NULL); printf("inside main created thread\n"); return 0; } 

After compilation, the answer will be found as follows:

 creating thread inside main created thread inside function inside function 

I understand that the answer may vary since return 0; can be called before printf executed in func. But how to arrive at the solution, inside function is printed twice?

When compiling with gcc -o temp thread1.c -lpthread on first start:

 creating thread inside main created thread 

on the second start:

 creating thread inside main created thread inside function inside function 

When compiling with gcc -pthread -o temp thread1.c On first start:

 creating thread inside main created thread inside function inside function 

I observed this behavior on

 gcc version: 4.4.3 (Ubuntu 4.4.3-4ubuntu5) Kernel release:2.6.32-24-generic glib version:2.11.1 
+8
c multithreading pthreads
source share
3 answers

I watched this problem on gcc version 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5), glib version 2.15 with the O2 flag. Without the optimization flag, this problem is not observed.

Why the conclusion is strange
The C language specification does not refer to any particular compiler, operating system or processor. He refers to an abstract machine, which is a generalization of real systems. This abstract machine (at least up to the C99 specifications) is single-threaded. Therefore, standard libraries (including printf ) are not required for streaming security by default. If you use standard library functions by threads (using some library, for example posix libpthread), you are responsible for adding synchronization (mutex, semaphore, condvar, etc.) before accessing non-standard library functions. If you do not, unexpected results may appear from time to time, and you should use them at your own risk.

Some analyzes in an environment where I can reproduce this problem
Analyzing the assembly generated for both versions of the flag, I can not find a significant difference (a noticeable event, printf converted to puts )

Looking for a source for puts

 int _IO_puts (str) const char *str; { int result = EOF; _IO_size_t len = strlen (str); _IO_acquire_lock (_IO_stdout); if ((_IO_vtable_offset (_IO_stdout) != 0 || _IO_fwide (_IO_stdout, -1) == -1) && _IO_sputn (_IO_stdout, str, len) == len && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) result = MIN (INT_MAX, len + 1); _IO_release_lock (_IO_stdout); return result; } #ifdef weak_alias weak_alias (_IO_puts, puts) #endif 

The problem seems to be in _IO_putc_unlocked('\n', _IO_stdout) . This can clear the stream and can be killed before updating the state of the stream.

Multithread coding training
When the main thread returns, it completes the entire process. This includes all other threads. So pass all the child threads to exit (or use pthread_kill ) and either exit the main thread using pthread_exit or use pthread_join .

+3
source share

For starters, as far as I remember, compiling with "-pthread" is equivalent to compiling with "-D_REENTRANT -lpthread", so the only difference is there. Note that printf, etc. They are not reentrant because they work with a global buffer.

Having said that, I, unfortunately, could not recreate the interesting part of your problem (your printf inside the target function of the stream seems to have been called twice). Each compilation method (-lpthread and -pthread) gives me the same result: I get fingerprints from inside main, but none of the print from the target of the thread (as you mentioned, you saw it when you first started). I think that this is just a synchronization problem, while the purpose of the stream does not “get close” to printing in front of the main outputs. In fact, just sleeping for 1/100 of a second, before returning from the main one, it gets me the seal of the target’s goal. Try and let us know what you see:

 #include<stdio.h> #include<stdlib.h> #include<limits.h> #include<string.h> #include<pthread.h> #include <unistd.h> void * func(void * temp) { printf("inside function\n"); return NULL; } int main() { pthread_t pt1; printf("creating thread\n"); pthread_create(&pt1,NULL,&func,NULL); printf("inside main created thread\n"); /* ZzzzzZZZ... */ usleep(10000); return 0; } 

I played with a delay time and even with 1/1000000 of a second: USleep (1); I still get all the expected printfs. As sleep latency decreases, printing is likely to occur out of order, which I expect to see.

So, regarding multiple prints: as mentioned above, printf, etc. work with global structures and are not reentrant. I would be interested to see your result if you reset stdout after your printf, all protected by a mutex:

 #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #include <pthread.h> #include <unistd.h> static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void * func(void * temp) { pthread_mutex_lock(&mutex); printf("inside function\n"); fflush(stdout); pthread_mutex_unlock(&mutex); return NULL; } int main() { pthread_t pt1; pthread_mutex_lock(&mutex); printf("creating thread\n"); fflush(stdout); pthread_mutex_unlock(&mutex); pthread_create(&pt1,NULL,&func,NULL); pthread_mutex_lock(&mutex); printf("inside main created thread\n"); fflush(stdout); pthread_mutex_unlock(&mutex); usleep(10000); return 0; } 

EDIT

Sorry, I was not 100% clear when I suggested using fflush () above. I believe that the problem is that you interrupt the time during which characters are pushed onto the screen and when the buffer is cleared. When the buffers then really turned red, you effectively pushed your line twice.

+1
source share

In general, you cannot assume that printf and associated memory structures are thread safe. It depends on how the stdio library was implemented. In particular, crashes can occur when threads and processes terminate, since the runtime library typically deletes the output buffers before exiting. I have already seen this behavior, and the solution is usually a mutex or semaphore to protect output operations (more precisely, to protect access to FILE objects).

+1
source share

All Articles