Причина, по которой некоторые печатают дважды (например, номер потока 9), заключается в том, что вы передаете указатель на переменную цикла в качестве входных данных для thread_operation.
for(j = 0; j < 10; j++){
err = pthread_create(&tid, NULL, thread_operation, &j);<---here
что & j в конечном итоге разыменовывается thread_operation:
void *thread_operation(void *arg){
int j =*((int*)arg);<---here
но в этот момент цикл может продвинуться, и значение j (в операции потока) будет таким, каким j окажется в цикле прямо сейчас. Способ исправить это - передать не указатель, а значение j в конструктор потока. Измените ваш pthread_create, чтобы передать значение:
pthread_create(&tid, NULL, thread_operation, (void*) j);
и в вашем потоке приведите значение из аргумента потока:
int j =(int)arg;
Теперь технически это зависит от того факта, что int
и void*
имеют одинаковый размер, тогда как в общем случае это не так. Но это будет работать до тех пор, пока вы не используете гигантские значения int
.
для всех остальных проблем @Intrepidd прав в использовании pthread_join, чтобы убедиться, что процесс не завершится до завершения всех ваших потоков.