Как P (& sem) и V (& sem) в семафоре влияют на код? - PullRequest
0 голосов
/ 08 июня 2019

У меня есть этот основной код, который выполняет pthread_create с функцией "doit" в качестве одного из ее параметров. У меня есть три функции doit, где в каждой из них P и V расположены по-разному или вообще не имеют P и V. Мой вопрос, как каждый из результатов будет отличаться? Более конкретно, что было бы возможным выходом для каждой функции doit?

Что я знаю до сих пор, так это то, что P (& sem) превратит значение sem в 0, а V превратит значение в 1. Однако мне трудно понять, как это повлияет на код.

Пока я думаю, что функция doit # 1 приведет к 1 2 3 поскольку printf и i = i + 1 хорошо защищены P (& sem) и V (& sem).

Кроме того, все возможные выходы с функцией doit # 2, по моему мнению, 1, 2, 3 /// 1, 3, 3 /// 2, 2, 3 /// 2, 3, 3 /// 3, 3, 3. пожалуйста, поправьте меня, если я ошибаюсь.

Однако я действительно не уверен, что произойдет с несколькими потоками, когда дело доходит до функции # 3 с точки зрения возможных выходных данных. Буду признателен за любую помощь, спасибо.

  sem_t sem;
  /* semaphore */


  int main(){
     int j;
     pthread_t tids[3];
     sem_init(&sem, 0,1);
     for (j=0; j<3; j++) {
        pthread_create(&tids[j], NULL, doit, NULL);
        }
     for (j=0; j<3; j++) {
        pthread_join(&tids[j], NULL);
        }
     return 0;
     }


  doit# 1.
  int i = 0;
  void *doit(void *arg){
     P(&sem);
     i = i + 1;
     printf("%d\n", i);
     V(&sem);
     }


  doit #2.
  int i = 0;
  void *doit(void *arg){
     P(&sem);
     i = i + 1;
     V(&sem);
     printf("%d\n", i);
     }


  doit #3.
  int i = 0;
  void *doit(void *arg){
     i = i + 1;
     printf("%d\n", i);
     }

1 Ответ

0 голосов
/ 08 июня 2019

Первая программа напечатает

1
2
3

Это единственная программа, где все обращения к i должным образом охраняются P / V .

Поведение двух других программ имеет значение undefined , поскольку запись в один поток может происходить одновременно с чтением в другом потоке и в соответствии с C115.1.2.4p25 :

Выполнение программы содержит гонку данных, если она содержит два конфликтующих действия в разных потоках, по крайней мере одно из которых не является атомарным, и ни одно не происходит раньше другого.Любая такая гонка данных приводит к неопределенному поведению.

и C11 5.1.2.4p4

Два вычисления выражений конфликтуют, если одно из них изменяет ячейку памяти, а другое считывает или изменяет одну и ту же ячейку памяти.

Часто эти виды заданий просят найти разницу между2 и 3. Они не правы.С точки зрения C вы уже открыли ящик Пандоры, и все возможно.

...