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));
Related
So I have a program which is supposed to have consumer and producer threads.
In the main method, I want to call init_consumers() which will call ptread_init()
Here is some code:
int init_consumers(char *quantity, pthread_t **cons, void *complex_obj)
{
//seting the limit acording to "quantity"
for (; i < limit; i++)
pthread_create(cons[i], NULL, &consumer, &complex_obj);
return(i);
}
the main:
#include <pthread.h>
#define MAX_PROD 50
#define MAX_CONS 50
///main entry point of the program
int main(int argc, char *argv[])
{
pthread_t prod[MAX_PROD];
pthread_t cons[MAX_CONS];
struct complex_obj *co;
//some code
co = create_cplx_obj();
//complex object manipulation code
init_producers(argv[2], &prod, co);
init_consumers(argv[3], &cons, co);
//more code
exit(0);
}
argv[2] and argv[3] is how many producers/consumers the user wants.
Also, the thread signature is: void *producer(void *args);
I still get problems with the * and &, so my problem is when making the method call and signature.
The error I was getting was
n_prod_n_cons.c:158:6: note: expected ‘pthread_t * {aka long unsigned int *}’ but argument is of type ‘pthread_t (*)[50] {aka long unsigned int (*)[50]}’ int init_producers(char *quantity, pthread_t *prod, void *complex_obj)
As indicated (tersely) in my comment, you have arrays of pthread_t in main(); pass them to the launchers just as you would an array of int. Make the signature of the launcher functions match what you'd do if you passed an array of int. Then use &array[index] to pass a pointer to a single row of the array to pthread_create(). That adds up to:
In main():
init_producers(argv[2], prod, co);
init_consumers(argv[3], cons, co);
(Your code was passing a pthread_t (*)[MAX_PROD] — pointer to a fixed size array of pthread_t — to the launcher functions, quite different from the signatures which expected a pthread_t **.)
The launchers look like:
int init_consumers(char *quantity, pthread_t *cons, void *complex_obj)
{
// setting the limit acording to "quantity"
for (; i < limit; i++)
pthread_create(&cons[i], NULL, consumer, &complex_obj);
return(i);
}
cons[i] is the ith entry in the array of pthread_t; passing its address give the pthread_create() function the pthread_t * it expects.
I wrote this small program for understanding pthread_create and pthread_join but I dont understand why the value of the variable data gets altered after thread_join. Its printed as 0 after the call to pthread functions.
#include <pthread.h>
#include <stdio.h>
void* compute_prime (void* arg)
{
int n = *((int*) arg);
printf("Argument passed is %d\n",n);
return (void *)n;
}
int main ()
{
pthread_t thread;
int data = 5000;
int value=0;
pthread_create (&thread, NULL, &compute_prime, &data);
pthread_join (thread, (void*) &value);
printf("The number is %d and return value is %d.\n", data, value);
return 0;
}
And the output is
Argument passed is 5000
The number is 0 and return value is 5000.
This is because pthread_join has the prototype void **. It expects a pointer to an object of type void *; it modifies this void * object. Now it so happens that you're running on a 64-bit arch, where data and value are both 32 bits, and laid out in memory sequentially. Modifying a void * object that is laid out in memory starting from the address of the int object value clobbers the int object data too, as these are both 32 bits - thus you will see that the data was overwritten. However, this is undefined behaviour so anything might happen.
Don't use casts as they will only serve to hide problems. Casting to a void * is especially dangerous as a void * can be converted to any other type implicitly, even to void **, even though usually it too would be incorrect. If you remove the cast, you most probably will get a warning or an error like
thrtest.c: In function ‘main’:
thrtest.c:16:31: error: passing argument 2 of ‘pthread_join’ from
incompatible pointer type [-Werror=incompatible-pointer-types]
pthread_join (thread, &value);
if compiling with warnings enabled.
If however you really want to do this, you must do it like this:
void *value;
pthread_join(thread, &value);
intptr_t value_as_int = (intptr_t)value;
Though it is not really portable either, as the conversion is implementation-defined.
The most portable way to return an integer is to return a pointer to a mallocated object:
int *return_value = malloc(sizeof (int));
*return_value = 42;
return return_value;
...
void *value;
pthread_join(thread, &value);
int actual = *(int *)value;
free(value);
Hi guys I'm having trouble with this code
int file_id;
void* wraper(void* p){
return (void)reader((int)p);
}
int main(int argc, char *argv[]){
srandom ((unsigned) time(NULL));
int i;
pthread_t tid[3];
for(i=0;i<3;i++){
pthread_t * temp = malloc(sizeof(tid[i]));
file_id=get_random(NB_FILES);
pthread_create(&tid[i], NULL,wraper,(void*)file_id);
}
and the compiler is giving me this
reader-thread.c: In function ‘wraper’:
reader-thread.c:59:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
return (void)reader((int)p);
^
reader-thread.c:59:5: error: void value not ignored as it ought to be
return (void)reader((int)p);
^
reader-thread.c: In function ‘main’:
reader-thread.c:70:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
pthread_create(&tid[i], NULL,wraper,(void*)file_id);
^
The objective is to create 3 threads and send them the file_id to the function reader, I can't see what I'm doing wrong
Your compiler is correct, you shouldn't ignore this, on many architectures pointers and int don't have the same width. The correct type, if you really have to, is to use uintptr_t or intptr_t.
Also casting the return of the function (that you didn't show us) to (void) makes no sense if you have to return a void*.
Casting the other way around from int to void* is almost as bad as 1.
In essence you shouldn't try to violate the call interface for thread functions. If you have to transmit data, pass a pointer to the data.
Also, please, when you post a question here, be sure that the error messages correspond to the code that you posted.
pthread_create(&Thread,NULL,ChildThread,(void *)100);
1) Can we pass the 4th argument of pthread_create as shown above? shouldn't it be a pointer variable?
Just an example (not meant to be correct way of doing it; but to serve as example code for anyone who want to play with it):
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
void *print_number(void *number) {
printf("Thread received parameter with value: %d\n", number);
return (void *)number;
}
int main(int argc, char *argv[]) {
pthread_t thread;
void *ret;
int pt_stat;
pt_stat = pthread_create(&thread, NULL, print_number, (void *)100);
if (pt_stat) {
printf("Error creating thread\n");
exit(0);
}
pthread_join(thread, &ret);
printf("Return value: %d\n", ret);
pthread_exit(NULL);
return 0;
}
This will lead to undefined behavior if the pointer value is greater then what an int can hold. See this quote from C99:
Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.
What (void *)100 means is take the integer value 100 and treat it as a pointer to some unspecified type of memory (i.e., (void *)). In that case, that means push the integer value 100 on the stack as an argument to pthread_create. Presumably, ChildThread casts the void * passed to it back to an int, then uses it as a number.
Fundamentally pointers are really just memory addresses. A memory address is just a number that describes a location in memory, so casting an int to a pointer of any type is legal. There are a few cases where casting an int to a pointer is absolutely the right thing to do and required, however, they tend to be rare. For example, if you are writing code for an embedded controller, and want write a driver for a memory mapped I/O device, then you might cast the device's base address as a pointer to an int or struct and then do normal C accesses through the pointer to access the device. Another example where casting ints to pointers, would be to implement the low-level virtual memory management routines to parcel out physical memory for an operating system.
The code you present is not uncommon and will work, assuming that the size of a pointer is at least big enough to hold the integer you are trying to pass. Most systems that implement pthread_create would probably have a 32-bit or 64-bit pointer, so your example is pretty likely to work. IMHO, it is a bit of an abuse, because 100 probably does not refer to a memory location in this case, and C does not guarantee that a void * is big enough to hold an int.
Taken from an excellent artice on POSIX Thread Progreamming . Must read for any newbie .
Example Code - Pthread Creation and Termination
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Explanation :
You can pass the 100 as the 4th argument to the pthread_create() . In the function PrintHello you can typecast the void* back into the correct type .
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;