When I try to compile the following code:
#include <pthread.h>
#include <stdio.h>
#define ARRAYSIZE 17
#define NUMTHREADS 4
struct ThreadData {
int start, stop;
int* array;
};
/* puts i^2 into array positions i=start to stop-1 */
void* squarer(struct ThreadData* td) {
struct ThreadData* data=(struct ThreadData*) td;
int start=data->start;
int stop=data->stop;
int* array=data->array;
int i;
for (i=start; i<stop; i++) {
array[i]=i*i;
}
return NULL;
}
int main(void) {
int array[ARRAYSIZE];
pthread_t thread[NUMTHREADS];
struct ThreadData data[NUMTHREADS];
int i;
/*
this has the effect of rounding up the number of tasks
per thread, which is useful in case ARRAYSIZE does not
divide evenly by NUMTHREADS.
*/
int tasksPerThread=(ARRAYSIZE+NUMTHREADS-1)/NUMTHREADS;
/* Divide work for threads, prepare parameters */
for (i=0; i<NUMTHREADS; i++) {
data[i].start=i*tasksPerThread;
data[i].stop=(i+1)*tasksPerThread;
data[i].array=array;
}
/* the last thread must not go past the end of the array */
data[NUMTHREADS-1].stop=ARRAYSIZE;
/* Launch Threads */
for (i=0; i<NUMTHREADS; i++) {
pthread_create(&thread[i], NULL, squarer , &data[i]);
}
/* Wait for Threads to Finish */
for (i=0; i<NUMTHREADS; i++) {
pthread_join(thread[i], NULL);
}
/* Display Result */
for (i=0; i<ARRAYSIZE; i++) {
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
I get this error:
warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type pthread_create(&thread[i], NULL, *squarer, &data[i]);
^
Does anyone know how to fix it?
Thanks
The function squarer has type void *(*)(struct ThreadData *), but pthread_create expects an arguments of type void *(*)(void *). Those types are incompatible.
Change your function to take a void * argument, then assign it to a struct ThreadData *.
void* squarer(void *td) {
struct ThreadData* data=td;
....
The 3rd parameter passed to pthread_create() has to be of type void * (*)(void *).
Yours is of type void * (*)(struct ThreadData * td).
To fix this change
void* squarer(struct ThreadData* td) {
struct ThreadData* data=(struct ThreadData*) td;
to become
void* squarer(void * td) {
struct ThreadData * data = td;
Related
Ive been beating my head against the wall for days about this because I cant seem to find a good solution to this issue. I need to pass two arrays into a threaded function using a structure. One array is the structure Im needing to sum and the other is where the result of that summation needs to be stored and then I need to sum them one final time in the main program to get the total value.
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#define NUMBER_OF_THREADS 2
typedef struct
{
double s[NUMBER_OF_THREADS];
double a[];
int tid;
} parmListType;
void *sum_arr(void *parms)
{
pthread_exit(NULL);
}
int main(int argc, char **argv)
{
pthread_t threads[NUMBER_OF_THREADS];
int status, i;
double arr[1000000]={};
double sum[NUMBER_OF_THREADS];
printf("debug_size_arr: %ld\n",sizeof(arr)/sizeof(double));
for(int i=0;i<sizeof(arr)/sizeof(double);i++)
{
arr[i]=i;
}
parmListType *parms;
for(i=0; i<NUMBER_OF_THREADS; i++)
{
printf("debug: Main here. Creating thread %d\n", i);
// dynamically create a structure to hold the parameter list
parms = (parmListType *)malloc( sizeof(parmListType));
//printf("debug_sizeof_paramA: %ld\n",sizeof(parms->a));
//parms->s[NUMBER_OF_THREADS/sizeof(double)]= *sum;
parms->tid = i;
status = pthread_create(&threads[i], NULL, sum_arr, (void *) parms);
if(status != 0)
{
printf("oops. pthread_create returned error code %d\n", status);
exit(-1);
}
printf("first for\n");
}
for(i=0; i<NUMBER_OF_THREADS; i++)
{
status=pthread_join(threads[i], NULL);
}
exit(0);
}
//// there are loads of errors in this code, I need guidance about how Im
////supposed to set this up right.
You can do st similar to the below:
struct ThreadArgs
{
int type;
//others
};
void* Thread(void* thread_args)
{
int type;
pthread_detach(pthread_self());
type = ((struct ThreadArgs *) thread_args)->type;
return NULL;
}
int main()
{
pthread_t thread_id;
struct ThreadArgs* thread_args;
thread_args = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs));
if (thread_args == NULL)
PanicWithError("malloc() failed");
thread_args->type = 1;
if (pthread_create(&thread_id, NULL, Thread, (void *) thread_args) != 0)
PanicWithError("pthread_create() failed");
while (1)
{}
return 0;
}
I have just started learning parallel programming using pthreads. So, for the learning purpose I tried sum of two integer arrays parallely. I have declared struct construct with three array variables a, b and c. I want to do addition of a, b and store the result in c.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#define MAX 6
struct data {
int a[MAX];
int b[MAX];
int c[MAX];
};
void *addition(void *index) {
struct data *d1 = (struct data *)index;
printf("value of d1 structure=%d\n", d1->a[0]);
}
int main() {
int i, j, t;
struct data *item = NULL;
pthread_t threads[MAX];
item = (struct data *)malloc(sizeof *item);
printf("enter the value for arrray a\n");
for (i = 0; i < MAX; i++) {
scanf("%d", &item->a[i]);
}
printf("enter the value of array b\n");
for (j = 0; j < MAX; j++) {
scanf("%d", &item->b[j]);
}
for (t = 0; t < MAX; t++) {
pthread_create(&threads[t], NULL, addition, (void *)&item);
}
}
Here, as of now I have not added the addition of arrays in the function addition(), because in pthread_create() when I am passing the three arguments with the help of structure, in function addition the variables a and b are not getting copied. Printing a is giving me garbage value. Can anybody help me how to copy the structure variable to the function argument called by pthread_create().
pthread_create Function :
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Kindly note (*arg) is pointer to the arg.
You have created struct data *item as a pointer then you are passing its address i.e. pointer to pointer.
pthread_create(&threads[t], NULL, addition, (void *)&item);
Change the call to
pthread_create(&threads[t], NULL, addition, (void *)item).
I am having issues trying to send multiple arguments to the pthread_create, the issue is basically because one of the arguments is another struct.
This is the node.
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#define NUM_THREADS 4
struct arr {
char line[10];
};
struct args {
struct arr record; int count; int init; int end;
};
void* processarr(void *arguments)
{
int count; int init; int end;
struct args *argstmp=arguments;
init=argstmp->init;
count=argstmp->count;
end=argstmp->end;
struct arr record[count];
record=(struct arr)argstmp->record;
printf("Some of the vals are init %d count %d end %d\n",init, count, end);
printf("vals like record 0\n", record[0].line);
pthread_exit(NULL);
}/*end of processarr*/
int main (int argc, char *argv[])
{
int line_count;
FILE *ptr_file;
char buf[10];
ptr_file =fopen(argv[ 1 ],"r");
if (!ptr_file)
return 1;
while (fgets(buf,10, ptr_file)!=NULL)
{
line_count++ ;
}
rewind(ptr_file);
struct arr record[line_count];
line_count=0;
while (fgets(buf,10, ptr_file)!=NULL)
{
line_count++ ;
buf[strcspn(buf, "\r\n")] = 0; /* Removing end null chars*/
strcpy(record[line_count].line,buf);
}
float grptmp,group, lgroup;
grptmp=line_count/NUM_THREADS;
int counter1,counter2,init,end;
counter2=1;
struct args myargs;
//processarr(record, line_count, init, end);
pthread_t threads[NUM_THREADS];
for (counter1=0;counter1<=line_count;counter1++)
{
if(counter2==NUM_THREADS)
{
end=line_count;
}else{
end=counter1+grptmp;
}
init=counter1;
myargs.record=*record;
myargs.count=line_count;
myargs.init=init;
myargs.end=end;
printf ("Run job #%d with paramts Init=%d and End=%d\n",counter2, init, end);
//call here
//struct arr *record; int count; int init; int end;
int rc;
long t;
for(t=0;t<NUM_THREADS;t++){
rc = pthread_create(&threads[t], NULL,processarr,&myargs);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
counter1=counter1+grptmp;
counter2++;
}
return 0;
}
So, when I send my arguments,the one stored inside myargs.record=*record, for some reason I am not able to "unpack" it once in the function.
The function is was defined as void to be able to catch the whole big argument, and I am trying to re-map everything there, the counts are working fine, but the one called record, that is actually another struct is not working, looks like a cast issue.
void* processarr(void *arguments)
{
int count; int init; int end;
struct args *argstmp=arguments;
init=argstmp->init;
count=argstmp->count;
end=argstmp->end;
struct arr record[count];
record=(struct arr)argstmp->record;
printf("Some of the vals are init %d count %d end %d\n",init, count, end);
printf("vals like record 0\n", record[0].line);
pthread_exit(NULL);
}
I am getting the following error when compiling.
test4.c: In function processarr:
test4.c:31:7: error: assignment to expression with array type
record=(struct arr)argstmp->record;
Any idea why this is not working? This last one was my last change using the casting (struct arr) in front of the argstmp (which is supposed to have everything inside).
Elaborating a little more on my response, this is what I would do using another struct to pass the arguments.
typedef struct {char line[10];}mystruct;
typedef struct {mystruct struct1;char line[10];}wrapper;
struct wrapper2 {mystruct struct1;char line[10];};
void unwrap(struct wrapper2 args){
printf("val is %s\n",args.line);
mystruct tmp=args.struct1;
printf("val inside structure is %s\n\n", tmp.line);
}
int main ()
{
mystruct names;
strcpy(names.line,"TEST");
struct wrapper2 wrapper1;
wrapper1.struct1=names;
strcpy(wrapper1.line,"Value1");
unwrap (wrapper1);
}
I hope this example helps you fix the issue, you just need to pass the same thing using the pthread_create.
Update:
The final code could look like this:
#include <pthread.h>
#include <stdlib.h>
struct mystruct {
int val;
};
void * func (void *args){
struct mystruct *st1=args;
printf("Thread created..%d\n", st1->val);
pthread_exit(NULL);
}
int main ()
{
/* Thread creation logic as void * (*)(void *)
int pthread_create (pthread_t *, const pthread_attr_t *,
void *(*)(void *), void *);
* */
struct mystruct mystruct1;
mystruct1.val=230;
pthread_t threads;
pthread_create(&threads,NULL,&func,&mystruct1);
pthread_exit(NULL);
return 0;
}
I recommend you read the actual manual of pthread_create.
http://man7.org/linux/man-pages/man3/pthread_create.3.html
I simply want to pass the value of an integer to a thread.
How can I do that?
I tried:
int i;
pthread_t thread_tid[10];
for(i=0; i<10; i++)
{
pthread_create(&thread_tid[i], NULL, collector, i);
}
The thread method looks like this:
void *collector( void *arg)
{
int a = (int) arg;
...
I get the following warning:
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
The compiler will complain if you don't cast i to a void pointer:
pthread_create(&thread_tid[i], NULL, collector, (void*)i);
That said, casting an integer to a pointer isn't strictly safe:
ISO/IEC 9899:201x
6.3.2.3 Pointers
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
so you're better off passing a separate pointer to each thread.
Here's a full working example, which passes each thread a pointer to a separate element in an array:
#include <pthread.h>
#include <stdio.h>
void * collector(void* arg)
{
int* a = (int*)arg;
printf("%d\n", *a);
return NULL;
}
int main()
{
int i, id[10];
pthread_t thread_tid[10];
for(i = 0; i < 10; i++) {
id[i] = i;
pthread_create(&thread_tid[i], NULL, collector, (void*)(id + i));
}
for(i = 0; i < 10; i++) {
pthread_join(thread_tid[i], NULL);
}
return 0;
}
There's a nice intro to pthreads here.
int is 32 bit, and void * is 64 bit in 64bit Linux; In that case you should use long int instead of int;
long int i;
pthread_create(&thread_id, NULL, fun, (void*)i);
int fun(void *i) function
long int id = (long int) i;
void *foo(void *i) {
int a = *((int *) i);
free(i);
}
int main {
int *arg = (char*)malloc(sizeof(char))
pthread_create(&thread, 0, foo, arg);
}
It better to use of a struct for send more parameters in one :
struct PARAMS
{
int i;
char c[255];
float f;
} params;
pthread_create(&thread_id, NULL, fun, (void*)(¶ms));
then you can cast params to PARAMS* and use of it in pthread routine:
PARAMS *p = static_cast<PARAMS*>(params);
p->i = 5;
strcpy(p->c, "hello");
p->f = 45.2;
I am attempting on creating multiple threads that each thread calculates a prime. I am trying to pass a second argument to a function using thread create. It keeps throwing up errors.
void* compute_prime (void* arg, void* arg2)
{
here is my main() with the create thread. &primeArray[i] after &max_prime is giving me the errors.
for(i=0; i< num_threads; i++)
{
primeArray[i]=0;
printf("creating threads: \n");
pthread_create(&primes[i],NULL, compute_prime, &max_prime, &primeArray[i]);
thread_number = i;
//pthread_create(&primes[i],NULL, compPrime, &max_prime);
}
/* join threads */
for(i=0; i< num_threads; i++)
{
pthread_join(primes[i], NULL);
//pthread_join(primes[i], (void*) &prime);
//pthread_join(primes[i],NULL);
//printf("\nThread %d produced: %d primes\n",i, prime);
printf("\nThread %d produced: %d primes\n",i, primeArray[i]);
sleep(1);
}
the error i get is:
myprime.c: In function âmainâ:
myprime.c:123: 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 * (*)(void *, void *)â
myprime.c:123: error: too many arguments to function âpthread_createâ
It works fine if i take out the second argument.
You can only pass a single argument to the function that you are calling in the new thread. Create a struct to hold both of the values and send the address of the struct.
#include <pthread.h>
#include <stdlib.h>
typedef struct {
//Or whatever information that you need
int *max_prime;
int *ith_prime;
} compute_prime_struct;
void *compute_prime (void *args) {
compute_prime_struct *actual_args = args;
//...
free(actual_args);
return 0;
}
#define num_threads 10
int main() {
int max_prime = 0;
int primeArray[num_threads];
pthread_t primes[num_threads];
for (int i = 0; i < num_threads; ++i) {
compute_prime_struct *args = malloc(sizeof *args);
args->max_prime = &max_prime;
args->ith_prime = &primeArray[i];
if(pthread_create(&primes[i], NULL, compute_prime, args)) {
free(args);
//goto error_handler;
}
}
return 0;
}
In case of std::thread, the user can pass arguments to the thread function in the following method
std::thread(funcName,arg1,arg2);
for instance,
//for a thread function,
void threadFunction(int x,int y){
std::cout << x << y << std::endl;
}
// u can pass x and y values as below
std::thread mTimerThread;
mTimerThread = std::thread(threadFunction,1,12);
This is the code of Manakarse , everything is really good but you need a
pthread_join(thread[i],NULL)
just to be sure all of threads will successfully execute before end of main thread("main will "waiting" while all of threads aren't finished yet)
;
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct
{
int stop_flag;
char name[30];
} _process_data;
typedef struct
{
int meter_no;
int port_no;
} _process_control;
typedef struct
{
_process_data *process_data;
_process_control *process_control;
} compute_prime_struct;
void *compute_prime (void *args)
{
compute_prime_struct *actual_args = args;
printf("actual_args->process_data->stop_flag [%d]\n",actual_args->process_data->stop_flag);
printf("actual_args->process_data->name [%s]\n",actual_args->process_data->name);
printf("actual_args->process_control->meter_no [%d]\n",actual_args->process_control->meter_no);
printf("actual_args->process_control->port_no [%d]\n",actual_args->process_control->port_no);
free(actual_args);
return 0;
}
void fill_data(_process_data *process_data,_process_control *process_control)
{
process_data->stop_flag=1;
process_data->name[0]='P';
process_control->meter_no=6;
process_control->port_no=22;
pthread_t tid;
compute_prime_struct *args = malloc(sizeof (*args));
args->process_data = malloc(sizeof (*args->process_data));
args->process_control = malloc(sizeof (*args->process_control));
memcpy (args->process_data, process_data, sizeof (args->process_data));
memcpy (args->process_control, process_control, sizeof (*args->process_control));
if(pthread_create(&tid, NULL, compute_prime, args))
{
free(args);
printf("Error here");
}
sleep(1);
}
int main()
{
_process_data process_data;
_process_control process_control;
fill_data(&process_data,&process_control);
return 0;
}