An argument to a pthread function might be another function?

I know how to pass a function as an argument to another function. But I don't know if the argument to the function passed by pthread is another function. Is it possible?

Here is an example of code that compiles OK but doesn't work:

#include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_t idThread; void aFunction(){ while(1){ fprintf(stderr,"I've been called!\n"); usleep(1000000); } } void * threadFunction(void *argFunc){ // Do here some stuff; // ... // Now call the function passed as argument void (*func)() = argFunc; } int thread_creator(void(*f)()){ // I want to use as argument for threadFunction the f function pthread_create(&idThread, NULL, threadFUnction, (void *)f); } int main(){ thread_creator(aFunction); while(1); return 0; } 
+4
source share
4 answers

It could be a function pointer if you want to bend the rules a bit. Strictly speaking, void * not guaranteed to hold a function pointer. Something like this (untested):

 void some_fun() { /* ... */ } void thread_fun(void *arg) { void (*fun)() = arg; } pthread_create(...., (void *) some_fun); 

EDIT

In your example, you also need to call the function through a function pointer. Sort of:

 void (*func)() = argFunc; funct(); /* <-- */ 
+7
source

Strictly speaking, this is not possible. According to the standard, a pointer to void can simply be converted to a pointer or from a pointer to an object type. On some architectures, function addresses are greater than object addresses.

C11, ยง 6.3.2.3 Pointers

A pointer to void can be converted to a pointer to or from a pointer to any type object. A pointer to any type of object can be converted to a pointer to void and vice versa; The result is compared with the original pointer.

Otherwise, this is a general extension.

C11, ยง J.5.7. Function Index

A pointer to an object or void can be transferred to a pointer to a function that allows you to call data as a function (6.5.4).

In your example, you are not calling func .

 #include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_t idThread; void aFunction(void) { while (1) { fprintf(stderr, "I've been called!\n"); usleep(1000000); } } void *threadFunction(void *argFunc) { void (*func)(void) = argFunc; func(); /* HERE */ } int thread_creator(void (*f)(void)) { pthread_create(&idThread, NULL, threadFUnction, (void *) f); } int main(void) { thread_creator(aFunction); while (1); return 0; } 
+3
source

To add to the answers already received:

Conceptually, function pointers can be passed in the same way as any other type of pointer, but - as indicated - void * not guaranteed to be large enough to hold a function pointer, only a data pointer.

A workaround for something like the pthread_create callback function is to wrap the desired function pointer in the structure that you use as user data:

 struct threadArg { void (*callback)(void); }; // ... struct threadArg *threadArg = malloc(sizeof(threadArg)); threadArg->callback = myFunction; pthread_create(&idThread, NULL, threadFunction, (void *) threadArg); 
+3
source

There is no need for questionable ghosts containing pointers to functions. An argument to a stream can be a pointer to a structure that can contain anything.

 #include <pthread.h> struct arg { void (*func)(void); int other_stuff; }; void function(void) { } void *thread_function(void *arg) { struct arg *a1 = arg; a1->func(); return NULL; } int main(void) { pthread_t tid; struct arg arg = {.func = function}; pthread_create(&tid, NULL, thread_function, &arg); . . . } 
0
source

Source: https://habr.com/ru/post/1433845/


All Articles