I am trying to create a simple program with thread support using Emscripten:
#include <stdio.h>
#include <pthread.h>
void *myThreadFun(void *vargp) {
printf("From Thread \n");
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t tid;
printf("Before Thread\n");
pthread_create(&tid, NULL, myThreadFun, NULL);
printf("Before join\n");
pthread_join(tid, NULL);
printf("After Thread\n");
return 0;
}
I am executed it in Firefox and I compile using -s USE_PTHREADS=1.
This is the output I got in the console:
Before Thread
Preallocating 1 workers for a pthread spawn pool.
Before join
But I expected:
Before Thread
Preallocating 1 workers for a pthread spawn pool.
Before join
After Thread
It is like the thread is not ending. Am I missing something?
I had the same issue. I fixed it by compiling with -s PTHREAD_POOL_SIZE=x with x = number of thread created.
Related
I'm new to C and multithreading programming, just a question on what happen if the main thread finish but peer threads are not, does the process still wait until all peer threads finish or the process terminates immediately right after the main thread is done?
When the main function returns, or you call exit, then the system will terminate the process and all threads running in that process.
If you have background (detached) threads that you want to keep running, you have to end the "main" thread only, not the process. How to do that is platform-dependent, but on POSIX platforms (e.g. Linux or macOS) then you call pthread_exit instead of exit.
If you don't have any background threads then you need to join all the running threads to keep them from being forcibly terminated.
Here is an example program which illustrates the preceding answer on GLIBC/Linux operating system. The program creates a detached secondary thread and if it is not passed a parameter, the main thread exits otherwise it calls pthread_exit():
#include <pthread.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
void *th_entry(void *p)
{
int i;
printf("Secondary thread starting...\n");
for (i = 0; i < 5; i ++) {
printf(".");
fflush(stdout);
sleep(1);
}
printf("\nSecondary thread exiting\n");
return NULL;
}
int main(int ac, char *av[])
{
int rc;
pthread_t tid;
printf("Main thread starting...\n");
rc = pthread_create(&tid, NULL, th_entry, NULL);
if (rc != 0) {
errno = rc;
fprintf(stderr, "pthread_create(): '%m' (%d)\n", errno);
return 1;
}
// Detach the secondary thread
rc = pthread_detach(tid);
if (rc != 0) {
errno = rc;
fprintf(stderr, "pthread_detach(): '%m' (%d)\n", errno);
return 1;
}
// Some dummy work
sleep(1);
if (av[1]) {
printf("Main thread exiting\n");
return 0;
} else {
printf("Main thread calling pthread_exit()\n");
pthread_exit(NULL);
}
return 0;
}
Compile it:
$ gcc td.c -l pthread
When the program is not passed any parameter, the main thread calls pthread_exit() and the process ends when the secondary thread finishes.
$ ./a.out
Main thread starting...
Secondary thread starting...
.Main thread calling pthread_exit()
....
Secondary thread exiting
$
When the program is passed a parameter, the main thread calls exit() (it returns 0 but it is equivalent) and the process ends immediately terminating the secondary thread:
$ ./a.out 1
Main thread starting...
Secondary thread starting...
.Main thread exiting
$
I'm new to C and I am trying to learn. I'm trying to implement multithreading in my program, but I'm having problems. The program (and the threads) should be going on running in a infinite loop, but actually the programs stops after few seconds. What can I do for having the program running forever? Am I doing something wrong?
#include <stdio.h>
#include <pthread.h>
void *func(void *threadid){
while (1)
{
/* do stuff, but the program terminates after that thread does few cycles */
}
}
int main(){
#define NUM_THREADS 800
pthread_t threads[NUM_THREADS];
int rc, i;
for (i=0; i < NUM_THREADS; i++)
{
rc = pthread_create(&threads[i], NULL, func, (void *)i);
if (rc)
{
printf("Error to create thread, #%d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
As soon as your main thread exits, the program terminates (and so do the threads). If you want your program to never end, you should add a while(1); at the end of you main while loop.
Note that this is not how to do it properly, your threads should have an end, and the master thread should wait for all the threads to be done, before exiting itself.
I am using the following code:
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void
clean(void *arg)
{
printf("thread clean: %ld\n", (unsigned long)arg);
}
void*
thread_template(void *arg)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_cleanup_push(clean, (void*)pthread_self());
printf("thread: %ld\n", (unsigned long)pthread_self());
while ( 1 ) {}
pthread_cleanup_pop(0);
pthread_exit((void*)0);
}
int
main(int argc, char const *argv[]) {
pthread_t tid;
pthread_create(&tid, NULL, thread_template, NULL);
// waiting for 2 seconds
sleep(2);
pthread_cancel(tid);
pthread_join(tid, NULL);
}
It works fine both on FreeBSD 11 and Ubuntu 16,
outputs are like this:
thread: 1994462320
thread clean: 1994462320
But on macOS, it seems pthread_cancel() doesn't affect the thread, main thread blocks at pthread_join(), the clean function never execute(only the first row was output).
So, what happened to macOS's pthread? or any wrong with my code ?
i have this piece of code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
int number;
pthread_mutex_t *mutex;
pthread_t *threads;
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
time_t rawtime;
struct tm * time_start;
time ( &rawtime );
time_start = localtime ( &rawtime );
printf ( "The number %ld thread is created at time %s \n",tid, asctime (time_start));
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int i,rc;
printf("give threads");
scanf("%d",&number);
mutex = calloc( number, sizeof(*mutex));
threads = calloc(number, sizeof(*threads));
for (i = 0; i < number;i++) {
pthread_mutex_init( &mutex[i],NULL);
}
for(i=0; i<number; i++){
printf("In main: creating thread %d\n", i);
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
return 0;
}
The purpose of this code is to ask the user to give the number of the threads that it is going to create and after the creation of the threads,the thread itself will print 2 messages saying the number of the thread and the time that it was created.
The problem is that inside the main the message "In main: creating thread" is showing up but the message inside the threads sometimes does not.
For example, it would create 3 threads and only 1 thread will show up its message and that thread also will not show up the time that was created. I dont know if there is something wrong with the code.
Root Cause:
Your main() exits before the child threads get an opportunity to complete their task.
Solution:
You need to make sure that the main() waits until all the threads have completed their work.
You need to use:
pthread_join()
to achieve this functionality. Add the following before returning from main():
for(i=0; i<number; i++)
{
pthread_join(threads[i], NULL);
}
Other problems:
You allocate memory dynamically but never deallocate it. Eventhough, the OS reclaims the memory once your program returns. It is a good practice to do so explicitly.
You created a mutex but you neither use it, nor deallocate it. But that seems to be code in progress.
Return from main() is equivalent to calling exit(...), which terminates the whole process. You may use pthread_join() to wait for each non-main thread, like another answer advises, or you may call pthread_exit(NULL) in the end of your main(): it would exit the initial thread, but other threads will continue to run.
I tried to compile this simple pthreads program with this command
$ gcc -pthread -o pthreads pthreads.c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
pthread_t mythread;
int ret;
ret = pthread_create( &mythread, NULL, myThread, NULL );
if (ret != 0){
printf( "Can't create pthread: %s", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg){
// Thread code goes here..
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
but when trying ./pthreads there is no output presented!!
You need to wait for the thread to finish. Otherwise you risk exiting before the thread starts executing.
...
pthread_create( &mythread, NULL, myThread, NULL );
...
// Wait for the thread to finish.
pthread_join( mythread, NULL);
You didn't wait for your thread to finish. You need to use pthread_join().
You problem comes from the fact that you're main thread is returning from main, and thus calling exit (or _exit). All running thread are killed when the program exit. In this case, the worker thread didn't have the time to execute before it is killed.
You can use pthread_join to wait for the completion of the thread before returning from main.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
void* thread_return;
pthread_t mythread;
int ret;
ret = pthread_create(&mythread, NULL, myThread, NULL);
if (ret != 0)
{
printf("Can't create pthread: %s\n", strerror(errno));
exit(-1);
}
ret = pthread_join(mythread, &thread_return);
if (ret != 0)
{
printf("Can't join pthread: %s\n", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg)
{
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
Sanjit's answer is certainly correct, but for the sake of enlarging your threads toolbox, you might also look at pthread_barrier_wait. When you have a simple program with a lot of threads and main looks like "start all worker threads and wait for them to finish", having main and all the workers simply wait on a barrier can be a nice way to avoid having to store all the worker thread ids and join them in a for loop. Barriers also have a lot of other neat uses that sometimes let you avoid unnecessary complexity from doing the same things with mutexes and condition variables.