Когда pthread_t имеет 0? - PullRequest
       7

Когда pthread_t имеет 0?

0 голосов
/ 09 июля 2019

Я создал потоки, используя pthread_create () в RHEL 7.2.pthread_create возвращает 0, но * поток (1-й параметр) равен 0.

знаете ли вы причину, по которой идентификатор потока равен 0?

pthread_t thread[6];
int nArg;

int nThread = pthread_create(&thread[0], NULL, funcA, &nArg);
if(0 > nThread)
    printf("failed");
else
    printf("thread started: %ld", thread[0]);

Вывод: поток запущен: 0

Ответы [ 3 ]

1 голос
/ 10 июля 2019

Я создал потоки, используя pthread_create () в RHEL 7.2. pthread_create возвращает 0, но * поток (1-й параметр) равен 0.

знаете ли вы причину, по которой идентификатор потока равен 0?

Если предположить, что на самом деле равно 0, что из этого? Это предполагает, что pthread_t является арифметическим типом, который не указан текущей версией POSIX, но если это так, то 0 является допустимым значением для него. Нет никакого документированного значения для определенных значений идентификатора потока, и, в частности, нет причин полагать, что потоку не следует присваивать 0 в качестве идентификатора, если это допустимое значение типа pthread_t.

Поскольку вы также упомянули возвращаемое значение pthread_create, я полагаю, вы можете подумать, что между ним и идентификатором потока существует какая-то связь. Никаких таких отношений не задокументировано, за исключением того, что значение идентификатора потока определяется после того, как pthread_create() возвращает только в том случае, если возвращаемое значение точно равно 0.

Но это указывает на проблему в вашем коде, на которую @ ErikAlapää впервые указала: pthread_create() входит в группу функций, которые возвращают номер ошибки непосредственно при ошибке, не группа, которая возвращает -1 при ошибке и ожидает от вас обращения к errno для номера ошибки. Номера ошибок положительные, поэтому на ваше условие if(0 > nThread) нельзя положиться, чтобы определить, не удалось ли pthread_create. Вы должны проверить ровно 0:

if (0 != nThread) {
    printf("failed");
} else {
    printf("thread started: %lu", (unsigned long) thread[0]);
}

Обратите внимание также на изменение формата и приведение ко второму вызову printf(). Вам нужен второй аргумент, чтобы в точности иметь тип, соответствующий директиве форматирования (раньше %ld, но теперь %lu), и это unsigned long int. Приведение допустимо, пока pthread_t является арифметическим или указательным типом, и на практике на компилятор можно положиться, чтобы отклонить код, если это что-то еще - скажем, структурный тип. Учитывая, что приведение необходимо (но, возможно, недостаточно) для получения известного типа, тип unsigned безопаснее, поскольку преобразование тогда имеет определенное поведение в случае, если исходное значение выходит за пределы диапазона для цели тип. Если у вас есть несоответствие типов, как вы могли бы иметь в исходном коде, то поведение не определено, и среди наиболее вероятных из бесчисленного множества возможных проявлений такого UB является то, что «0» печатается несмотря на то, что thread[0] не равно нулю .

Учитывая все вышесказанное, я не воспроизвожу вашу проблему, даже с вашим оригинальным, некорректным кодом. Я склонен подозревать, что ваш pthread_create вызов не удался, возможно, потому, что вы используете библиотеку C, созданную без поддержки потоков, или вместо функциональных связывает фиктивные процедуры pthreads. Убедитесь, что при сборке вы указали правильные параметры для программы pthreads. Например, если вы компилируете с gcc, вы можете указать опцию -pthread. Если у вас есть отдельные шаги компиляции и компоновки, используйте эту опцию для обоих.

0 голосов
/ 10 июля 2019

Тип pthread_t непрозрачен в соответствии с POSIX. Это может быть любой тип. В частности, это не обязательно должен быть арифметический тип (указатель или целое число). Соответствующая реализация потоков POSIX может использовать struct для pthread_t.

Если pthread_t является целочисленным типом, нет запрета на его нулевое значение. Это может быть индекс потока в некотором массиве, например, первый поток получает нулевую позицию.

Мы не удивлены, что стандартный дескриптор входного файла равен нулю.

0 голосов
/ 09 июля 2019

Попробуйте вместо этого проверить возвращаемое значение относительно ровно нуля. Только если возвращаемое значение равно 0, создание потока завершилось успешно.

На странице руководства errno написано «Допустимые числа ошибок - это положительные числа». Например, в Linux ошибочные номера ошибок примерно равны 0 и 200.

Кроме того, распечатайте сообщение, соответствующее полученному вами ошибочному номеру, например, используя. PError ().

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