1
votes

this is the right use of pthread_create with no warning:

#include <pthread.h>
#include <stdio.h>
void  *check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, check , (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

but the following code can also run well, just change void *check to void check:

#include <pthread.h>
#include <stdio.h>
void check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, check, (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

if i change check to &check, it can also run well

#include <pthread.h>
#include <stdio.h>
void check(void *temp) {
    int* i = (int *)temp;
    printf("%d\n", *i);
}
int main(void) {
    pthread_t check_thread;
    int i = 1;
    pthread_create(&check_thread, NULL, &check, (void  *)&i);
    pthread_join(check_thread, NULL);
    return 0;
}

i see the thrid argument of pthread_create is: void *(*start_routine) (void *)
can someone tell me what does it mean?

3
This looks like C, so what's the reason for tagging the different language C++? And what's specifically unclear about the documentation? - too honest for this site
As others have stated, this isn't C++, but the third argument of pthead_create is a function pointer. - not an alien

3 Answers

1
votes

The deal of the C standard is to write portable code, that could run on any conforming platform. The fact that this runs on your platform without visible errors, does not mean that it would on other platforms. Reasons for failure could e.g be that pthread_join could try to access a hardware register with the return value.

1
votes

It is nothing but a function pointer. Lets break it down. void *(*start_routine) (void *)

void* -> return type of function
start_routine -> function pointer name 
void* -> argument type

the address of the function you pass will be assigned to function pointer start_routine and start_routine will be invoked as new thread from kernel.

1
votes

Per the POSIX standard for pthread_create():

SYNOPSIS

#include <pthread.h>

int pthread_create(pthread_t *restrict thread,
       const pthread_attr_t *restrict attr,
       void *(*start_routine)(void*), void *restrict arg);

That means that the third argument to pthread_create() must be a function pointer of the form void *(*start_routine)(void*). The function pointer passed must refer to a function declared and defined as

void *start_routine( void *arg )
{
    void *ptr = ...;

    ...
    return( ptr );
}

Period. End of discussion. Full stop.

You are invoking undefined behavior by not passing a function of the type void *(*start_routine) (void *) as the third argument to pthread_create().

Per J.2 Undefined behavior, paragraph 1 of the C standard:

The behavior is undefined in the following circumstances:

...

  • A pointer is used to call a function whose type is not compatible with the referenced type.

"Works with no observed issue" is covered by "undefined behavior". "Program crashes" is also covered.