какой тип необходим pthread_create для третьего аргумента - PullRequest
0 голосов
/ 09 декабря 2018

это правильное использование pthread_create без предупреждения:

#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;
}

, но следующий код также может работать хорошо, просто измените void * check на 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;
}

если я поменяю check на & 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;
}

я вижу, что аргумент thth из pthread_create: void * (* start_routine) (void *)
может кто-нибудь сказать мне, что он делаетзначит?

Ответы [ 3 ]

0 голосов
/ 09 декабря 2018

Это не что иное, как указатель на функцию.Давайте разберемся с этим.void * (* start_routine) (void *)

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

адрес передаваемой функции будет присвоен указателю функции start_routine, а start_routine будет вызываться как новый поток из ядра.

0 голосов
/ 09 декабря 2018

Per стандарт POSIX для 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);

Это означает, чтоТретий аргумент pthread_create() должен быть указателем на функцию вида void *(*start_routine)(void*).Переданный указатель функции должен ссылаться на функцию, объявленную и определенную как

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

    ...
    return( ptr );
}

Период.Конец обсуждения.Полная остановка.

Вы вызываете неопределенное поведение , не передавая функцию типа void *(*start_routine) (void *) в качестве третьего аргумента pthread_create().

Per J.2 Неопределенное поведение , параграф 1 стандарта C :

Поведение не определено в следующих обстоятельствах:

...

  • Указатель используется для вызова функции, тип которой не совместим с указанным типом.

"Работает без наблюдаемой проблемы"покрыт" неопределенным поведением ".«Сбои программы» также рассматриваются.

0 голосов
/ 09 декабря 2018

Задача стандарта C состоит в написании переносимого кода, который может работать на любой соответствующей платформе.Тот факт, что это работает на вашей платформе без видимых ошибок, не означает, что это будет на других платформах.Например, причина сбоя может заключаться в том, что pthread_join может попытаться получить доступ к аппаратному регистру с возвращаемым значением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...