I am new to threads.
I have written a sample program to create a thread.
#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 is found to be :
creating thread
inside main created thread
inside function
inside function
I understand that answer may vary as return 0;
may be called before the printf
in func is executed.
But how come in the solution, inside function
is printed two times?
On compiling With gcc -o temp thread1.c -lpthread
on first run:
creating thread
inside main created thread
on second run:
creating thread
inside main created thread
inside function
inside function
On compiling with gcc -pthread -o temp thread1.c
On first run:
creating thread
inside main created thread
inside function
inside function
I have 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
In manufacturing, threading is the process of creating a screw thread. More screw threads are produced each year than any other machine element.
On a multiprocessor or multi-core system, multiple threads can execute in parallel, with every processor or core executing a separate thread simultaneously; on a processor or core with hardware threads, separate software threads can also be executed concurrently by separate hardware threads.
A process refers to the code and data in memory segments into which the operating system loads a program. Simply put, a process is a program that is loaded into the memory to be executed by the processor. A thread is the minimum execution unit of code managed by the operating system.
The order in which the threads should be run will be controlled by the order in which you insert them into the ArrayList. You call the runThreads method with a String and the threads will run in that sequence.
I observed this issue on gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5), glib version 2.15 with O2
flag. Without any optimization flag, this issue is not observed.
Why the output is strange
The C language specification does not make reference to any particular compiler, operating system, or CPU. It makes reference to an abstract machine that is a generalization of actual systems. This abstract machine (atleast up to C99 specs) is single threaded. So standard libraries (including printf
) are not required to be thread safe by default. If you are using standard library functions across the threads (using some library for example posix libpthread), you are responsible for adding synchronization (mutex, semaphore, condvar etc) before accessing non-entrant standard library functions. If you don't, there may be surprising results from time to time and you should use at your own risk.
Some analysis at the environment where I can reproduce this issue
Analyzing the assembly generated for both version of flag, I can not find any significant difference (Onething noticeable, printf
s are converted to puts
)
Looking at the 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
It seems the problem lies in _IO_putc_unlocked('\n', _IO_stdout)
. This may flush the stream and may get killed before updating the stream state.
Learnings for multithreaded coding
When the main thread returns, it terminates the entire process. This includes all other threads. So signal all children threads to exit (or use pthread_kill
) and either make main thread exit with pthread_exit
or use pthread_join
.
In general you can't assume that printf and related memory structures are thread-safe. It depends on the way stdio library has been implemented. In particular, malfunctions may happen when threads and processes are terminating, since the runtime library usually flushes the output buffers before exiting. I have already seen such a sort of behavior, and the solution is usually a mutex or semaphore to protect the output operations (more precisely, to protect the accesses to FILE objects).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With