Динамическая синхронизация вызова pthread требуется (???) - PullRequest
0 голосов
/ 30 марта 2012

Я пытаюсь написать код, используя потоки posix, но я застрял с первого шага и, честно говоря, я не могу понять, почему. Я знаю, что моя проблема, вероятно, связана с некоторой синхронизацией, но я не могу понять это.

В основном у меня есть следующее:

while(1){
  int x = getX();
  pthread_t t;
  printf("Main: %d\n",x);
  pthread_create(&t, NULL, process_x, &x);
}

Когда я пытаюсь вывести значение x из основного, а также из функции process_x, я получаю что-то вроде этого:

Основной: 1

Основной: 2

Основной: 3

Основной: 4

Основной: 5

Process_x: 5

Что мне здесь не хватает?

---- РЕДАКТИРОВАТЬ -----

ОК, возможно, мне нужно предоставить больше информации. Функция getX получает данные из сокета и возвращает идентификатор, в то время как для наших нужд теперь process_x просто печатает полученный аргумент.

Ответы [ 3 ]

1 голос
/ 30 марта 2012

Необходимо учитывать, что вы передаете адрес x потоку, а затем, не дожидаясь окончания печати потока, изменяете его значение.Очевидно, это будет означать, что, если несколько итераций закончатся до того, как поток начнет печатать свое значение, значение изменится.*pthread_join и дождитесь окончания потока.Это по сути бесполезно.Потому что тогда какой смысл создавать новый поток?

ИЛИ

2) Выделите новый адрес для каждого потока и дайте потоку освободить его после завершения печати. ​​

то есть malloc новое целое число, присвойте этому целому число x, передайте новое целое число malloc d потоку, и пусть поток free сделает это.

0 голосов
/ 02 апреля 2012

Очевидно, что использование malloc не работает, потому что оно устанавливает x в 0, поэтому процесс всегда читает 0. Но благодаря идеям allones я наконец-то заставил его работать, используя условную переменную, и теперь все в порядке.Вот код.

int main{
  pthread_t t;
  int x;
  while(1){
    pthread_mutex_lock(&receive);
    x = getX();
    printf("Main: %d\n",x);
    pthread_create(&t, NULL, process_x, &x);
    pthread_cond_wait(&goOn, &receive);
    pthread_mutex_unlock(&receive);
  }
}

void *process_x(void* arg){
  pthread_mutex_lock(&receive);
  int x = *(int *) arg;
  pthread_cond_signal(&goOn);
  pthread_mutex_unlock(&receive);
}
0 голосов
/ 30 марта 2012

Поток не будет выполнен, как только вы создадите его с помощью вызова pthread_create. Планировщик может решить оставить его в очереди. За это время ваш цикл while выполнялся 5 раз, и значение x могло бы также измениться на 5. Теперь, когда ваши потоки в конечном итоге запланированы, он (они) видит только последнее значение вашего x и, следовательно, только для печати 5.

Я сильно подозреваю, что Process_x был напечатан только один раз?

Не существует способа по умолчанию для выполнения pthreads в каком-либо определенном порядке. Вам нужно использовать некоторые методы синхронизации, такие как семафоры. Также, если вы хотите, чтобы Process_x напечатал все ваши значения, преобразуйте x в массив и передайте x[i] в качестве аргумента pthread_create

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