Print in single Pthread - c

I'm trying to implement a program using Pthreads in C. Now, I've tried to let a single thread print "Hi":
void * generator(void *arguments){
printf("Hi");
return NULL;
}
int main(int argc, const char* argv[]){
pthread_create(&threads_ids[0], NULL, &generator, NULL);=
}
This doesn't work and doesn't print anything. However, when I put the creation of the pthread in a for loop it does print "Hi", but at each execution the occurrence differs.
Is this normal behaviour, and if so; how can I fix it? Thanks in advance!

It's because your main thread returns and thus exits the process. It means the thread you created never gets a chance to run.
Unlike just returning from main(), calling pthread_exit(0) from main(), will let the other thread continue executing.
Alternatively, you can wait for the thread to complete execution by calling pthread_join() on the thread you created.
When you execute in a loop, probably some of the threads you create gets executed before main thread exits, and thus appears to "work" (prints some Hi).
But it does have the same problem as the code you posted.

Related

If main is a thread as well in c, why doesn't it run with other threads

I read that main() is single thread itself, so when i create 2 threads in my program like this;
#include<stdio.h>
#include<pthread.h>
#include<windows.h>
void* counting(void * arg){
int i = 0;
for(i; i < 50; i++){
printf("counting ... \n");
Sleep(100);
}
}
void* waiting(void * arg){
int i = 0;
for(i; i < 50; i++){
printf("waiting ... \n");
Sleep(100);
}
}
int main(){
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, counting, NULL);
pthread_create(&thread2, NULL, waiting, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
int i = 0;
for(i; i < 50; i++){
printf("maining ... \n");
Sleep(1000);
}
}
Is main really a thread in that case?
in that case if in main in sleep for some time, shouldn't the main give the CPU to other threads?
Is main a threads itself here? I am confused a bit here.
Is there a specific order to main thread execution?
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
You asked the thread to wait until thread1 terminates and then wait until thread2 terminates, so that's what it does.
I read that main() is single thread itself
No, you have misunderstood. Every C program has a function named main(). C language semantics of the program start with the initial entry into that function. In that sense, and especially when you supply the parentheses, main(), is a function, not a thread.
However, every process also has a main thread which has a few properties that distinguish it from other threads. That is initially the only thread, so it is that thread that performs the initial entry into the main() function. But it is also that thread that runs all C functions called by main(), and by those functions, etc., so it is not, in general, specific to running only the code appearing directly in the body of main(), if that's what you mean by "main() is a single thread itself".
, so when i create 2 threads in my program like this; [...] Is main really a thread in that case?
There is really a main thread in that case, separate from the two additional threads that it starts.
in that case if in main in sleep for some time, shouldn't the main give the CPU to other threads?
If the main thread slept while either of the other two were alive, then yes, one would expect one or both of the others to get (more) CPU time. And in a sense, that's exactly what happens: the main thread calls pthread_join() on each of the other threads in turn, which causes it to wait (some would say "sleep") until those threads terminate before it proceeds. While it's waiting, it does not contend with the other threads for CPU time, as that's pretty much what "waiting" means. But by the time the main thread reaches the Sleep() call in your program, the other threads have already terminated and been joined, because that's what pthread_join() does. They no longer exist, so naturally they don't run during the Sleep().
Is main a threads itself here?
There is a main thread, yes, and it is the only one in your particular process that executes any of the code in function main(). Nothing gets executed except in some thread or other.
I am confused a bit here. Is there a specific order to main thread execution?
As already described, the main thread is initially the only thread. Many programs never have more than that one. Threads other than the main one are created only by the main thread or by another thread that has already been created. Of course, threads cannot run before they are created, nor, by definition, after they have terminated. Threads execute independently of each other, generally without any predefined order, except as is explicitly established via synchronization objects such as mutexes, via for-purpose functions such as pthread_join(), or via cooperative operations on various I/O objects such as pipes.
main() is not a thread but a function, so here's a clear "no" to your initial claim. However, if you read a few definitions of what is a thread, you will find that it is something that can be scheduled, i.e. an ongoing execution of code. Further, a running program will not be able to actually do anything without "ongoing execution of code" without e.g. main() as first entrypoint. So, definitely, every code executed by a program is executed by a thread, without exceptions.
BTW: You can retrieve the thread ID of the current thread. Try running that from main(). It will work and give you a value that distinguishes this call from calls from other threads.

A strange result in a simple pthread code

I wrote the following code:
#include <pthread.h>
#include <stdio.h>
void* sayHello (void *x){
printf ("Hello, this is %d\n", (int)pthread_self());
return NULL;
}
int main (){
pthread_t thread;
pthread_create (&thread, NULL, &sayHello, NULL);
printf("HERE\n");
return 0;
}
After compiling and running I saw 3 different types of outputs.
Only "Here" was printed.
"Here" and 1 'sayHello' message.
"Here" and 2 'sayHello' messages.
Of course I'm OK with the second option, but I don't understand why the 'sayHello' massege can be printed 0 or 2 times if I created only one thread?
You can't say when the thread starts to run, it might not start until
after you return from main which means the process will end and the thread with it.
You have to wait for the thread to finish, with pthread_join, before leaving main.
The third case, with the message from the thread printed twice, might be because the thread executes, and the buffer is written to stdout as part of the end-of-line flush, but then the thread is preempted before the flush is finished, and then the process exist which means all file streams (like stdout) are flushed so the text is printed again.
For output 1:
your main function only create a pthread, and let it run without waiting for it to finish.
When your main function return, Operating system will collect back all the resources assigned to the pprocess. However the newly created pthread might have not run.
That is why you only got HERE.
For output 2:
your newly created thread finished before main function return. Therefore you can see both the main thread, and the created thread's output.
For output 3
This should be a bug in glibc. Please refer to Unexpected output in a multithreaded program for details.
To make the program always has the same output
pthread_join is needed after pthread_create

how does calling pthread_join multiple times work?

I am getting back into using pthreads and the definition of pthread_join bothers me.
It says
"The pthread_join() function shall suspend execution of the calling
thread until the target thread terminates, unless the target thread
has already terminated. On return from a successful pthread_join()
call with a non-NULL value_ptr argument, the value passed to
pthread_exit() by the terminating thread shall be made available in
the location referenced by value_ptr. When a pthread_join() returns
successfully, the target thread has been terminated. The results of
multiple simultaneous calls to pthread_join() specifying the same
target thread are undefined. If the thread calling pthread_join() is
canceled, then the target thread shall not be detached."
I am trying to understand how, if I call pthread_join for one thread, then call pthread_join to start a second thread, the two threads are started, even though I imagine, the second pthread_join cannot be called because the first join has suspended the main thread from executing, and running the next line until pthread_exit is called from within the thread joined.
In particular, I imagine, the first pthread_join must wait until the specified thread has called pthread_exit, only then it should continue. However this is not the case, as I can do:
#include <pthread.h>
#include <stdio.h>
int avail = 0;
void *consumer(void *unused)
{
while (1) {
if (avail > 0) {
--avail;
puts("consumed");
}
}
}
void *producer(void *unused)
{
while (1) {
++avail;
puts("produced");
}
}
int main(int argc, char **argv)
{
pthread_t c_thread;
pthread_t p_thread;
pthread_create(&c_thread, 0, consumer, 0);
pthread_create(&p_thread, 0, producer, 0);
pthread_join(c_thread, 0);
pthread_join(p_thread, 0);
return 0;
}
ignoring the problem of possible race conditions to try to reduce code size, why are both the threads working, despite the first join suspending the main thread (thus, preventing the next join from being called, in my mind).
I would really like to understand how this works.
Thanks ahead of time.
Threads run concurrently, starting sometime during or after the call to pthread_create. Calling pthread_join has nothing to do with starting or running the thread, it simply waits until it exits. Both your threads have already been running and are still runnable at the point you enter and block on the first join and they will continue to run. The only thing blocked by the first join is your main thread.
The threads do not start in pthread_join, but rather in pthread_create. I mislead myself into thinking pthread_join was used to actually start the thread, whereas it is a non-busy wait for the specific thread to return before the main thread continues it's execution, in my case, main returns before the threads get a chance to call the puts function.
The second pthread_join in my code is never actually called, because main is indeed suspended from the first pthread_join waiting on c_thread to return. The second join in this particular scenario is a "no operation" and the program never actually gets to it because consumer never actually returns.

main() does not terminate after successful pthread_join

I have a program that starts a pthread and later on waits for the termination of this thread before it returns. The code is something like:
int main(int32_t argc, char* argv[]) {
pthread_t t;
/* initialization and other stuff
...
*/
printf("join result:%d\n", pthread_join(t, 0));
return 0;
}
The program prints, as it is supposed to: join result: 0. So the join works and t is finished. Nevertheless the program does not stop execution. I can only force it to stop if I insert a command exit(0) (or some other number) before the return 0 line.
However, if I remove the line with the pthread_join call the program exits flawlessly.
How is this even possible? What could keep a program from finishing execution after all sub-threads are joined?
EDIT: I just found out that gdb tells me I get a segmentation fault after the execution of the last line with }. Nevertheless I have no idea what is going on behind the scenes:
Program received signal SIGSEGV, Segmentation fault.
0x000000060003aa10 in ?? ()
I think it may be possible that a stack corruption occurs in the main thread. From windows i know that before executing main, the adress of the exit_process function is pushed onto the stack. Then return 0 performs an exit_process call. If in your case the stack was corrupted, it's possible the pointer to exit_process was replaced with an invalid pointer.

Passing char[N] as thread argument in c?

Heres my code:
void *PrintLine(void *line)
{
printf("Line: #%s\n", (char *)line);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
char line[80];
while(fgets(line,sizeof(line),fp))
{
pthread_create(&threads[rt], NULL, PrintLine, (void*)line);
}
fclose(fp);
}
Please dont tell me that running a thread only to print a file line doesn't make sense, I removed a lot of code so its easier to read and understand my problem.
As you would guess this code doesn't work, what should I do to be able to print/use "line" inside the thread?
You're passing a pointer to line to the newly created thread, when your thread gets around to use line , perhapse fgets have written something else to it. Or perhaps it's in the middle of writing something when your thread accesses it.
You can pass a copy of the line you've read, remember to free() it when you're done with it inside you thread.
char *copy_of_line = strdup(line);
if(copy_of_line)
pthread_create(&threads[rt], NULL, PrintLine, copy_of_line);
You need pthread_join(3) in the main thread to wait for completion of each thread you spawned. Otherwise the main thread might end the process before other threads have a chance to do the printing (and also to make sure the stack memory you point spawned threads to is still in scope).
Edit:
Then post "real" code, or at least "working" code. We are not mind readers.
Another obvious error is that main threads overrides the buffer the other threads are supposed to be printing. There's no guarantee that at some point the string in that buffer is not zero-terminated. You really need to make a copy in the main thread before giving it to other threads.
Two immediately obvious problems:
you only have instance of line (think about it)
there is no guarantee that printf is thread-safe
Your problem is that all your threads use the same line buffer so a new line might be read before the other one is printed.

Resources