There is a pthread_create() function, the template of which looks like this:

 int pthread_create(pthread_t *pth, pthread_attr_t *att, void * (*function)(void *), void *arg); 

And I have some questions about this feature:

1) The function call in different sources looks different, which one is correct and is there any difference at all?

 void * fun(void *arg){ int count = * (int *)arg; printf("Thread %d\n", count); pthread_exit(NULL); } int main(void) { pthread_t thread; int count = 1; pthread_create(&thread, NULL, fun, &count); // первый способ pthread_create(&thread, NULL, &fun, &count); // второй способ pthread_exit(NULL); } 

2) Why, when we pass the function fun() pthread_create() function, we don’t pass any argument to it? Instead, I read somewhere that the fourth argument of the pthread_create() function is passed to the fun() function, but I don’t understand how this is done

3) The pthread_create() ) function first takes a pointer to pthread_t * , is this done to save memory, etc., or because the address plays a role? Just the code below proves that the address does not matter:

 void * fun(void *arg){ int count = * (int *)arg; printf("Thread %d\n", count); pthread_exit(NULL); } int main(void) { int i = 0; int *status; while(i < 10){ pthread_t thread; status = malloc(1); *status = i++; pthread_create(&thread, NULL, fun, (void *)status); printf("%ld\n", thread); } 

Here 10 threads are created, and the address of the thread does not change.

  • one
    A pointer to a function can be passed to both fun and &fun (in this case there is no difference). Calling fun somewhere inside int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) already in the new thread is written like this: start_routine(arg); - avp
  • one
    More precisely, of course, the call itself is already carried out in the clone system call - avp
  • one
    By the way, your example of creating threads in a loop is not quite correct, malloc should not be called from 1, but from sizeof(int) (yes, in standard implementations in both cases, enough memory will be allocated (most likely 16 (maybe 8) bytes) ) - avp
  • @avp so my status is of type int, won't it automatically multiply by the size of the type? - Egor Filatov

1 answer 1

a template that looks like this: this is called a signature

1) in the case of b, both options are normal (as I recall).

2) the function address is passed to pthread_create. Therefore, there are no brackets. If there were brackets, the function would be called. pthread_create creates the thread itself (it is hidden in the depths of the operating system. And then it makes the transition to the function that was passed to it as an argument. And also carefully puts the parameter on the stack.

3) according to the documentation

On success, pthread_create () returns 0; on line, it returns the number of threads to be undefined.

In principle, the function could return pthread_t, but many problems arise here. For example, how to check whether or not a thread has been created, what to do with the variable pthread_t, when the thread ends - whether to call a function for cleaning. And many other problems. In languages ​​like python, you can return a tuple of two values, and in C, you would need to return a pointer to the structure, and then clean the memory.

But the question is, why this variable (of type pthread_t)? and this is the handle that will control the flow. Other thread functions take this variable as an argument. For example, pthread_join, to wait for execution.

In your case, "it does not matter," because you create threads and just let them go free.