Я создал потоки, используя 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
. Если у вас есть отдельные шаги компиляции и компоновки, используйте эту опцию для обоих.