I want to write a multi threaded program in c language. I use posix thread library.
I write the following code:
#include<stdio.h>
#include<pthread.h>
void *put (int *arg)
{
int i;
//int * p;
// p=(int*)arg;
for(i=0;i<5;i++)
{
printf("\n%d",arg[i]);
}
pthread_exit(NULL);
}
int main()
{
int a[5]={10,20,30,40,50};
pthread_t s;
pthread_create(&s,NULL,put,a);
printf("what is this\n");
return 0;
}
I just want my thread just show the items in the array. The program compiled with following warning:
tm.c:19: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type
/usr/include/pthread.h:227: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int *)’
When I run the program I got the out put of main thread but not the value stored in array.
Now can anyone tell me what I'm doing wrong?
How to send the array as an argument in the thread function?
If I just changed the code little bit the compile time warning resolved the changed code is following:
#include<stdio.h>
#include<pthread.h>
void *put (void *arg)
{
int i;
int * p;
p=(int*)arg;
for(i=0;i<5;i++)
{
printf("\n%d",p[i]);
}
pthread_exit(NULL);
}
int main()
{
int a[5]={10,20,30,40,50};
pthread_t s;
pthread_create(&s,NULL,put,a);
printf("what is this\n");
return 0;
}
But the output does not change. Can any one tell me what i did wrong? What is the proper way to send array to a thread function (put in this case)?
Your code creates the thread and then the process exits by reaching the end of main. You have to wait for the thread to have a chance to execute, by calling pthread_join, or sleeping for a bit.
First of all, you need to wait for the thread to finish before returning from main().
Another problem with this code is that the array a is allocated on the stack of the main() routine and is thus potentially invalid in the context of a different thread. You should heap allocate a with a call to malloc().
If you wait for the thread to finish in main() then a is probably valid since the stack frame for main() will still exist. However, any future refactorings are liable to cause you grief so please switch to using malloc().
Try to wait for your thread to execute, add
pthread_join(s, NULL);
before your return 0;
Related
I think the print result should be 500, but the result was weird - it said 32728, which is meaningless.
#include<stdio.h>
#include<pthread.h>
void* testFunction(void*);
int main(void)
{
void* result;
pthread_t tid;
pthread_create(&tid, NULL, testFunction, NULL);
pthread_join(tid, &result);
printf("%d\n", *((int*)result));
}
void* testFunction(void* args)
{
int time;
time = 500;
pthread_exit((void*)&time);
}
In this code, this is the flow of what I thought
(void*)result has time's address.
(int*)result has time's address. Because of (int*), the program should know result variable is referring to int-type variable.
*((int*)result) means the value of what result variable refers to, so it would be time's value, which is 500.
Can you let me know what I thought wrong?
The problem is that time no longer exists by the time you come to check it. One way around that is to play with the casting. Instead of
pthread_exit((void*)&time);
use
pthread_exit((void*)time);
Then, when you are extracting the result, use
*((int) result)
Another minimal fix is to make time a static. That way, it is not stored in the stack and always exists.
What's wrong is that time is going out of scope when the thread function exits, meaning that dereferencing its address is undefined behaviour. And you are dereferencing after that, since it happens after the pthread_join() call.
There's a chance that something else will be using that memory (probably on the stack but no mandated, since a stack isn't itself mandated), which would explain the strange value.
But, regardless of what's actually happening, it's not something you're allowed to do in C. Or, more correctly, you can do it, just don't expect sane results.
As others already pointed out, the problem is that the pointer received by pthread_join() points nowhere the moment the function returned. As the memory allocate for int time has already been deallocated, as the function has already ended.
There are two possibilities to have pthread_join() return a pointer to valid memory:
Have the thread function allocate it dynamically.
#include <stdlib.h> /* For malloc() and free(). */
#include <stdio.h>
#include <pthread.h>
void* testFunction(void* pv_unused)
{
int * ptime = malloc(sizeof *ptime);
/* Add error checking/handling here! */
*ptime = 500;
pthread_exit(ptime);
}
int main(void)
{
...
pthread_join(tid, &result);
printf("%d\n", *((int*)result));
free(result); /* Free the memory that has been allocated by the thread-function. */
}
Pass a pointer to valid memory to the thread-function.
#include <stdio.h>
#include <pthread.h>
void* testFunction(void* pv_time)
{
int * ptime = pv_time;
*ptime = 500;
pthread_exit(ptime);
}
int main(void)
{
pthread_t tid;
int time;
pthread_create(&tid, NULL, testFunction, &time);
{
void * pv;
pthread_join(tid, &pv);
if (pv != &time)
{
/* Something went wrong! */
}
}
printf("%d\n", time);
}
I am trying to create dynamic number of thread.....
#include<stdio.h>
#include<pthread.h>
void* thread_function(void)
{
printf("hello");
}
int main(int argc,char *argv[])
{
int noOfThread= atoi(argv[1]);
pthread_t thread_id[noOfThread];
int i;
int status;
for(i=0;i<noOfThread;i++)
{
pthread_create (&thread_id[i], NULL , &thread_function, NULL);
}
for(i=0;i<noOfThread;i++)
pthread_join(thread_id[i],NULL);
}
3 errors:
implicit declaration of function atoi....
passing arguement 3 of 'pthread_create' from incompatible pointer type
expected 'void * (*)(void *)' but arguement is of typr'void * (*) (void)'......
There are several issues here:
You need to include stdlib.h for the declaration of atoi()
A pthread task function has a void* argument. This will fix issue #2 and #3.
(http://man7.org/linux/man-pages/man3/pthread_create.3.html).
void* thread_function(void* arg);
To be most portable and compliant with older C compilers, you should allocate your pthread_t array using malloc explicitly. Make sure to check for a NULL return value and free the memory later in this case. Or you can declare a maximum number of threads to allocate and use a constant array size.
pthread_t* thread_id = malloc(noOfThread*sizeof(pthread_t));
I originally had a global variable for my fibonacci variable array, but found out that is not allowed. I need to do elementary multithreading and handle race conditions, but I can't get past feeding an int as a void argument in pthread create. I've tried using a constant pointer with no luck. For some strange reason the void* gets past the first boolean test but not the else if:
$ gcc -o fibonacci fibonacci.c
fibonacci.c:22:16: warning: comparison between pointer and integer ('void *' and 'int')
else if (arg == 1)
~~~ ^ ~
1 warning generated.
My code is a mess and I am getting really confused because I have rewritten it so many times. If I cast all the args in my thread run function as ints I get a segmentation fault 11, which makes sense. All attempts at passing the i index by address and dereferencing it have failed, as it is a void and can't be used as an int. Can you suggest something else?
#include<stdio.h> //for printf
#include<stdlib.h> //for malloc
#include<pthread.h> //for threading
#define SIZE 25 //number of fibonaccis to be computed
int *fibResults; //array to store fibonacci results
void *run(void *arg) //executes and exits each thread
{
if (arg == 0)
{
fibResults[(int)arg] = 0;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else if (arg == 1)
{
fibResults[(int)arg] = 1;
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
else
{
fibResults[(int)arg] = fibResults[(int)arg -1] + fibResults[(int)arg -2];
printf("The fibonacci of %d= %d\n", (int)arg, fibResults[(int)arg]);
pthread_exit(0);
}
}
//main function that drives the program.
int main()
{
pthread_attr_t a;
fibResults = (int*)malloc (SIZE * sizeof(int));
pthread_attr_init(&a);
for (int i = 0; i < SIZE; i++)
{
pthread_t thread;
pthread_create(&thread, &a, run,(void*) &i);
printf("Thread[%d] created\t", i);
fflush(stdout);
pthread_join(thread, NULL);
printf("Thread[%d] joined & exited\t", i);
}
return 0;
}
You don't need the cast in the call to pthread_create() — the conversion to void * is automatic.
In the thread function, you could use
int i = *(int *)arg;
However, you've now got a synchronization problem; all the threads are using the same (pointer to the same) integer variable, and you can't predict which value they're going to see because of scheduling issues. The per-thread data needs to be 'per thread'.
So, there are various ways around that. In this context, I'd probably use
#include <stdint.h>
and in main():
pthread_create(&thread, &a, run, (void*)(uintptr_t)i);
and then in the thread function:
int i = (uintptr_t)arg;
Now the casts — the double cast even — is necessary. The cast to uintptr_t ensures the integer value is big enough to hold a pointer; the cast to void * is needed because there isn't an implicit cast from any integer type to void *. This ensures each thread function invocation has a different value. Sharing a pointer to an int means that everything is uncontrolled.
In the run() function you should do:
void *run(void *ptrarg) //executes and exits each thread
{
int arg = *((int *)ptrarg);
if (arg == 0)
....
....
and in rest of the run(), you don't need to cast the arg. Replace (int)arg with arg.
EDIT:
The way you are passing the argument to fun() while creating threads may cause race condition because all threads will be using same pointer. Check the #Jonathan's answer to avoid this problem.
#efuddy. Instead of (int)arg you should use (int *)arg to properly cast the **void pointer* void *arg
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#define N_ASS 4
pthread_t tid[N_ASS];
//mutex
pthread_mutex_t mutex;
//variabili condition
pthread_cond_t c_ass[N_ASS], c_pass[N_PASS];
void * checkDoc ()
{
printf("do stuff\n");
}
int main()
{
int err;
int i = 0;
for(i;i<N_ASS;i++){
err = pthread_create (&tid[i], NULL, checkDoc(), NULL);
pthread_cond_wait(&c_ass[i],&mutex);
}
for(i=0;i<N_ASS;i++)
pthread_cond_signal(&c_ass[i]);
for(i=0;i<N_ASS;i++) {
err = pthread_join(tid[i],NULL);
printf("%d joined\n",i);
}
printf("End\n");
}
I just want to say that I'm a little noob who is just learning and this is my first question, if I have to do something else just tell me and I'll do it!
So this is the code, I got one first problem, it makes segmentation-fault and I don't know why.
The output is:
do stuff //1,2,3 or 4 time
Segmentation fault
Nothing else, i runned at least 20 time.
You should be getting compiler warnings here, as the thread function (or rather what is supposed to be the thread function) doesn't return anything.
This will lead to undefined behavior because you don't pass a pointer to the checkDoc function to pthread_create, you actually call the checkDoc function, and use the returned pointer as the pointer to the thread function. As the checkDoc function doesn't actually return anything you will have undefined behavior, and most likely a crash.
Simple solution? Don't call the checkDoc function:
pthread_create (&tid[i], NULL, checkDoc, NULL)
// ^^^^^^^^
// No longer calling the function
And if you state that a function returns a value, you should actually do it. If the returned value is not used then just return NULL.
Also, in C when you declare a function without any formal arguments, it's the same thing as saying that the function accepts any number of arguments of any type. POSIX thread functions must specifically accept a void * argument. If you do not use the argument in the thread function, then simply don't name the argument:
void * checkDoc (void *) { ... }
This last bit also has implications for the main function, as the C specification explicitly says that the main function should either take two arguments (an int and an char *[]), or be void. If you have a function which doesn't take any arguments you must explicitly say that by using void as argument.
There are also other issues with your code. Like you not initializing the structures you use properly. Or like you waiting for the condition variable right after creating the each thread, and as you don't signal the condition variable until after you start waiting for it then you will wait forever and the code will not continue to the part where you actually call the signalling function.
I have a question about C concurrency programming.
In the pthread library, the prototype of pthread_join is
int pthread_join(pthread_t tid, void **ret);
and the prototype of pthread_exit is:
void pthread_exit(void *ret);
So I am confused that, why pthread_join takes the return value of the process as a pointer to a void pointer from reaped thread, but pthread_exit only takes a void pointer from the exited thread? I mean basically they are all return values from a thread, why there is a difference in type?
In pthread_exit, ret is an input parameter. You are simply passing the address of a variable to the function.
In pthread_join, ret is an output parameter. You get back a value from the function. Such value can, for example, be set to NULL.
Long explanation:
In pthread_join, you get back the address passed to pthread_exit by the finished thread. If you pass just a plain pointer, it is passed by value so you can't change where it is pointing to. To be able to change the value of the pointer passed to pthread_join, it must be passed as a pointer itself, that is, a pointer to a pointer.
It because every time
void pthread_exit(void *ret);
will be called from thread function so which ever you want to return simply its pointer pass with pthread_exit().
Now at
int pthread_join(pthread_t tid, void **ret);
will be always called from where thread is created so here to accept that returned pointer you need double pointer ..
i think this code will help you to understand this
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
void* thread_function(void *ignoredInThisExample)
{
char *a = malloc(10);
strcpy(a,"hello world");
pthread_exit((void*)a);
}
int main()
{
pthread_t thread_id;
char *b;
pthread_create (&thread_id, NULL,&thread_function, NULL);
pthread_join(thread_id,(void**)&b); //here we are reciving one pointer
value so to use that we need double pointer
printf("b is %s\n",b);
free(b); // lets free the memory
}
The typical use is
void* ret = NULL;
pthread_t tid = something; /// change it suitably
if (pthread_join (tid, &ret))
handle_error();
// do something with the return value ret