Как работает эта программа с потоками? - PullRequest
1 голос
/ 17 апреля 2019

Я пытаюсь изучить основы программирования потоков в c. И я обнаружил некоторую проблему, которую не могу понять. В программе пишут пять раз по пять. (Почему только пять? Почему не 1,2,3 или 4) и какая разница, когда я комментирую строку sleep (5) и нет?

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *dretva (void *x)
{
   sleep(2);
   printf("%d\n", *((int *)x));

return NULL;
}
int main()
{
   pthread_t id[5];
   int i;
   for(i=0;i<5;i++)
   {
       pthread_create(&id[i], NULL, dretva, (void*)&i);
   }    
   sleep(5); // why is different when this line is commented?
return 0;
}

Ответы [ 4 ]

3 голосов
/ 17 апреля 2019

В этом случае вы не можете точно предсказать вывод, потому что порядок выполнения потоков не гарантирован. И из-за sleep в каждом из потоков, так (в данном конкретном случае) случается, что значение i уже увеличено до 5 в цикле for до того, как первый поток будет выполнен.

Если вы хотите увидеть вывод i в порядке возрастания, просто вызовите pthread_join в цикле for.

for(i=0;i<5;i++)
{
    pthread_create(&id[i], NULL, dretva, (void*)&i);
    pthread_join(id[i], NULL);
} 

См. Демо

1 голос
/ 17 апреля 2019

Программа пишет пять раз по пять. (Почему только пять? Почему не 1,2,3 или 4)

Когда все потоки начали выполняться, значение iбыло уже установлено на 5 в основной теме.Но 5 не всегда печатать 5 раз.Каким бы ни было значение i во время выполнения потока, оно будет напечатано.

Какая разница, когда я комментирую строку sleep (5)

Разработчик этого кода заставляет основной поток ждать 5 секунд.Вы должны использовать объединение, чтобы заблокировать основной поток, пока другие потоки не вернутся.

1 голос
/ 17 апреля 2019

Вы, скорее всего, здесь находитесь в состоянии гонки.Суть в том, что, как указал Навин Кумар, к тому времени, когда ваши потоки станут активными, содержимое по адресу i равно 5, следовательно, каждый из ваших потоков выводит на печать то, что он находит по адресу i.Если вы в качестве альтернативы предоставите значение, вы должны получить желаемый результат.С помощью инструкции sleep вы отправляете свой основной поток в фоновый режим, сохраняя содержимое по адресу i в сохранности.Без этого утверждения ваш основной поток завершается, освобождая память по адресу i.В результате ваши темы могут найти случайные числа для печати.Если вы хотите избежать этого, попробуйте познакомиться с pthread_join.

0 голосов
/ 17 апреля 2019

Вы передаете адрес i в качестве аргумента. После окончания цикла значение i будет равно 5. Все потоки спят в течение 2 секунд и выводят одинаковое значение.

(* аннулируются) & я

pthread_create(&id[i], NULL, dretva, (void*)&i);

Вы можете использовать массив для хранения информации.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *dretva (void *x)
{
   sleep(2);
   printf("%d\n", *((int *)x));

return NULL;
}
int main()
{
   pthread_t id[5];
   int args[5];
   int i;
   for(i=0;i<5;i++)
   {   int j;
       args[i] = i; // storing tid
       pthread_create(&id[i], NULL, dretva, &args[i]);
   }    
   sleep(5);
return 0;
}
...