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.
Related
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.
pthread_create in a for loop, this is my code
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
pthread_mutex_t mutex;
void* helloWorld(void *i) {
pthread_mutex_lock(&mutex);
printf("This is a thread %d\n", *((int*) i));
pthread_mutex_unlock(&mutex);
return 0;
}
int main() {
pthread_mutex_init(&mutex, NULL);
pthread_t threads[4];
int i;
printf("Main Message\n");
for (i = 0; i < 4; i++) {
pthread_create(&threads[i], NULL, helloWorld, &i);
}
for (i = 0; i < 4; i++) {
pthread_join(threads[i], NULL);\
}
pthread_mutex_destroy(&mutex);
return 0;
}
The order doesn't really matter as long as all 4 threads are working.
I've tried to use mutex but it didn't solve the issue.
My current output is pretty random, it can be 0000 or 0112 or anything else.
The problem is two-fold:
First of all you don't have control over when the threads run or in which order.
You pass the same pointer to all threads.
You can solve the second issue by passing the value if i to the threads. This is one of the few cases where it's considered okay to pass values instead of pointers:
pthread_create(&threads[i], NULL, helloWorld, (void*)(uintptr_t) i);
Then in the thread
printf("This is a thread %d\n", (int)(uintptr_t) i);
The first issue, about the order, you have to come up with some other way to synchronize the threads and how they notify each other. For example by using four condition signals, one for each thread, that you signal in the order you want the threads to execute.
In this code, I'm trying to create an array of threads. I've set the pthreads value to 1. In the for loop, the address, ID, and "created" gets printed, but the function never seems to execute as I don't get a print.
The seg fault actually happens at pthread_join at the bottom, but it certainly has to be caused by the creation since the function never runs, right? producers[0] is the only thread since I'm just testing 1. The create function passes an (ID address, NULL, the void * function(), and void* arguments) like it's supposed to. It has to be something obvious but I've tried to figure it out for so long I'm empty.
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
FILE* inputfp = threadstruct->inputFiles[0];
hostname = (char*)malloc((MAXNAME+1)*sizeof(char));
while(fscanf(inputfp, hostname) > 0){
printf("%s",hostname);
}
return 0;
}
int main(int argc, char *argv[]){
int pthreads = atoi(argv[1]); //always 1
ThreadStruct threadstruct;
pthread_t producers[pthreads];
for(int i=0;i<pthreads;i++){
printf("in pthread loop\n");
printf("%p \n",&producers[i]);
printf("%ld \n",producers[i]);
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
}
pthread_join(producers[0], NULL);
}
Your code works in my side and would not produce the seg fault.
Here is the print out info:
$ ./pthread
in pthread loop
0xffffcb70
6444554784
in pthread loop
in producer
0xffffcb78
64
in pthread loop
in producer
0xffffcb80
1
in pthread loop
in producer
0xffffcb88
4299166064
in pthread loop
in producer
0xffffcb90
6443761969
in pthread loop
in producer
0xffffcb98
6445451520
in pthread loop
in producer
0xffffcba0
314761761601
in producer
exit main thread
Your code here:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
return 0;
}
int main(int argc, char *argv[]){
int pthreads = 7;
ThreadStruct threadstruct;
pthread_t producers[pthreads];
for(int i=0;i<pthreads;i++){
printf("in pthread loop\n");
printf("%p \n",&producers[i]);
printf("%ld \n",producers[i]);
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
}
pthread_join(producers[0], NULL);
printf("exit main thread\n");
}
you don't seem to check if the thread is actually created or not, in other words you don't seem to validate the return type of pthread_create and straight calling pthread_join probably leading to Undefined behavior, in case pthread_create fails.
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
from pthread_join
The pthread_join() function shall fail if:
EINVAL The implementation has detected that the value specified by thread does not refer to a joinable thread.
ESRCH No thread could be found corresponding to that specified by the given thread ID.
however there are cases where pthread_join with invalid thread handle seg faults.
a piece of extract from the link above
"*Passing invalid handle to pthread_join is like passing invalid pointer to a system call.
The implementation may detect it and signal it in errno, but it may crash as
well.
There are 2 different POSIX threads implementations on Red Hat Linux
linuxthreads, where pthread_t handle is a small integer (and the number of
threads is substantially limited)
NPTL (the default, pthread_t is internally a pointer so that there are no
arbitrary thread limits)
You can request the old-fashioned threading library with LD_ASSUME_KERNEL=2.4.19
in the environment.
For NPTL where pthread_t is a pointer, pthread_join detects some invalid
handles where it can be done cheaply. But detecting all possible invalid
handles would be very costly (the implementation would basically have to take
a global lock and iterate over all currently running threads, comparing the
handle with each of them. With say 100000 running threads you can see how
costly it is).
This testcase works on SuSE since SuSE only ships the old-fashioned non-scalable
linuxthreads implementation.*"
from pthead_create
RETURN VALUE
On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
perhaps something like this
if( pthread_create(&producers[i], NULL, producer, (void *) &threadstruct) ) {
perror("something wrong .. ");
exit(1);
}
Firstly check the return value of pthread_create() to check whether it was successful or not. For e.g
int ret = pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
if(ret) {
fprintf(stderr, "failed to create thread %s\n",strerror(ret));
exit(EXIT_FAILURE);
}
And Also it's advised to use pthread_join() for all the threads not only first thread, as if you want to wait for thread/s to terminate before further processing in main thread as mentioned here. Also check the return value of pthread_join().
Sample Code
#include<stdio.h>
#include<string.h>
#include<stdint.h>
#include<stdlib.h>
#include<pthread.h>
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
return 0;
}
int main(int argc, char *argv[]){
int pthreads = 5;
int ret;
ThreadStruct threadstruct;
pthread_t producers[pthreads];
/* create threads */
for(intptr_t itr = 0;itr < pthreads; itr++){
printf("in pthread loop\n");
//printf("%p \n",&producers[itr]);
//printf("%ld \n",producers[itr]);
ret = pthread_create(&producers[itr], NULL, producer, (void *) &threadstruct);
if (ret) {
fprintf(stderr, "failed to create thread #%ld - %s\n",(long)itr, strerror(ret));
exit(EXIT_FAILURE);
}
}
/* join all threads */
for(intptr_t itr = 0; itr < pthreads; itr++){
printf("In main: joining thread #%ld\n", (long)itr);
ret = pthread_join(producers[itr], NULL);
if (ret) {
fprintf(stderr, "failed to join thread #%ld - %s\n",(long)itr, strerror(ret));
exit(EXIT_FAILURE);
}
}
//pthread_exit();
return 0;
}
it works in my system, hope it works for you also.
I want to create a program that creates a new thread each time a specific method is called. Here is my working code so far:
#define NUMBER_OF_THREADS 3
pthread_t threads[NUMBER_OF_THREADS];
pthread_attr_t attr;
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld running...\n",tid);
// ...
printf("Thread %ld completed...\n",tid);
pthread_exit((void*) t);
}
void createNewThread(int number){
printf("running createNewThread(%d)\n", number);
pthread_t tid;
int rc = pthread_create( &tid, &attr, BusyWork, (void *) (long)number);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
int main(int argc, char *argv[]) {
int i, rc;
//Set up thread attributes
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
//Arbitary amount of calls (My real program will call the createNewThread() funcion multiple unkown amount of times)
createNewThread(15);
createNewThread(27);
createNewThread(62);
createNewThread(500);
createNewThread(8864);
createNewThread(99999);
//Free attributes
pthread_attr_destroy(&attr);
//Wait for other threads still running
// HOW CAN I DO THIS????
/*for (i=0; i< NUMBER_OF_THREADS; i++){
rc = pthread_join( ??? , NULL); //TODO
if (rc){
printf("ERROR: return code from pthread_join() %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %d\n", i);
}*/
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // (?) Is this part nessassary as we are on the main thread and soon to exit the program
return 0;
}
However as you can see in my code there is a few issues! For example, how can I wait for all processes to complete for the code I am using, as I am not keeping track of the thread number. Also when a thread "BusyWork" is done it does not clean up after it self and left as an orphan process.
One idea I had was to use a vector to keep track of each thread number and then use that for the final join at the end of main. However the problem with that is the array list can easily get very large and will never shrink even though a thread is complete.
Detach the threads, don't join them. Before you create a thread, increment a counter protected by a mutex. Right before a thread terminates, acquire the mutex and decrement the counter. Now you know all threads are done when the counter reads zero. You can use a condition variable to make the counter waitable if you like.
I'm trying to make a simple program using pthreads, want to make 6 threads and pass index to all of them. here's the code:
#include <pthread.h>
#include <stdio.h>
#define num_students 6
void thread_starter();
int main() {
pthread_t thread1[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
}
sleep(1);
}
void thread_starter(void* a) {
printf("Thread %i \n", *((int*)a));
}
And the output:
Thread 2
Thread 3
Thread 2
Thread 4
Thread 5
Thread 5
why do they have commmon names? what's wrong?
Thanks
You're passing a stack address from the main thread into all the child threads. There is no guarantee when these threads will be scheduled so you have no way of knowing whether the main thread will have updated its stack variable by the time each child gets around to reading it.
To avoid this, you need to allocate memory for the data being passed to each thread.
The easiest way to do this in your example is to use another automatic variable to store the data being passed to the new threads
void thread_starter(void* a);
int main() {
pthread_t thread1[num_students];
int thread_data[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
thread_data[i] = i;
pthread_create(&thread1[i], NULL, thread_starter, &thread_data[i]);
}
sleep(1);
}
Note also that you can avoid having to cast thread_starter if you give it the correct signature in your forward declaration.
For more complex programs you may need to dynamically allocate memory for each thread instead, passing ownership of that memory to the new threads.
int main() {
pthread_t thread1[num_students];
int i = 0;
for(i = 0; i<num_students; i++) {
int* data = malloc(sizeof(*data));
*data = i;
pthread_create(&thread1[i], NULL, thread_starter, data);
}
sleep(1);
}
void thread_starter(void* a) {
printf("Thread %i \n", *((int*)a));
free(a);
}
Finally, using sleep(1) isn't a very rigorous way of ensuring that all your threads will be run. It'd be better to use pthread_join instead
for(i = 0; i<num_students; i++) {
pthread_join(thread1[i], NULL);
}
sleep is not the correct tool to wait for spawned threads, use pthread_join for this.
Your main function terminating is equivalent to calling exit for the whole program and killing all the other threads.
Try This for Variation
void thread_starter(void* a) {
// Put a sleep(1) Here and see you will get even bizarre results
printf("Thread %i \n", *((int*)a));
}
Ok the problem here is of course
the race condition at this point here
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
lets say the first thread is created and the value at q is 0
now assume that before executing the statement Here
printf("Thread %i \n", *((int*)a));
if the main thread loops further and executes this statement here
int q = i;
again, then the q value changes (because its a reference) hence the problem
well one way to avoid this is to copy this reference variable in a local variable in thread routine also use mutex.
Sorry I was on a Hurry some more tips from my side
#define num_students 6
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // A Global Mutex
Will aquire a lock Here
pthread_mutex_lock( &mutex );
printf("\n Got Mutex %d\n", i);
int q = i;
pthread_create(&thread1[i], NULL, (void *) &thread_starter, (void *)&q);
and will release the lock Here in child Routine
int i = *((int*)a);
sleep(1);
pthread_mutex_unlock( &mutex );
printf("Thread %i \n", i);
P.S - Remove un necessary Prints and Sleeps where ever not applicable