статическое хранилище с функциями pthread - PullRequest
2 голосов
/ 29 февраля 2012

Я практиковал некоторые многопоточные программы, но я не мог понять логику этого вывода.

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

int print_message(void* ptr);

int main()
{
pthread_t thread1,thread2;
char *mesg1 = "Thread 1";
char *mesg2 = "Thread 2";

int iret1, iret2;

pthread_create(&thread1, NULL, print_message, (void *)mesg1);
pthread_create(&thread2, NULL, print_message, (void *)mesg2);

pthread_join(thread1,(void*)&iret1 );
pthread_join(thread2, (void*)&iret2);

printf("Thread 1 return : %d\n", (int)iret1);
printf("Thread 2 return : %d\n", (int)iret2);
return 0;

}

int print_message(void *ptr)
 {
char *mesg;
static int i=0;
mesg = (char *)ptr;
printf("%s\n",mesg);
i++;
return ((void*)i);

}

Я ожидал вывода

Thread 1
Thread 2
Thread 1 return : 1
Thread 2 return : 2

, но я получаю вывод

Thread 1
Thread 2
Thread 1 return : 0
Thread 2 return : 2

Могут ли некоторые объяснить мне это?И, пожалуйста, укажите, есть ли ошибки в использовании функций pthread.

Ответы [ 2 ]

4 голосов
/ 29 февраля 2012

Переменная i является общей для обоих потоков, потому что это static. Поведение изменения переменной между несколькими потоками не определено, поэтому фактически и вывод, который вы получаете, и вывод, который вы хотите получить, являются «неправильными» в том смысле, что компилятор не обязан их передавать вам. Фактически мне удалось изменить вывод в зависимости от уровня оптимизации, который я использовал, и он, несомненно, будет отличаться в зависимости от платформы.

Если вы хотите изменить i, вы должны использовать мьютекс:

int print_message(void *ptr)
{
  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  char *mesg;
  static int i=0;
  int local_i;

  mesg = (char *)ptr;
  printf("%s\n",mesg);
  if (pthread_mutex_lock(&mutex) == 0) {
    local_i = ++i;
    pthread_mutex_unlock(&mutex);
  }
  return ((void*)local_i);
}

Если вы не используете мьютекс, вы никогда не будете уверены , чтобы получить результат, который, по вашему мнению, вы должны получить.

3 голосов
/ 29 февраля 2012

Есть несколько хороших книг о многопоточности.Мне показалось довольно интересным "Программирование с помощью потоков Posix" , но существуют более свежие книги.

Вы читали какую-либо из них или хороший учебник pthreads онлайн?

По сути, каждый поток исходного кода программы может не просматривать память так же интуитивно, как вы ожидаете.( когерентность кэша , мультиобработка , модель памяти , C11 ...)

Практически говоря, любойдоступ к данным, разделяемым между потоками, должен быть защищен синхронизацией примитивами, например, мьютексами или rwlocks

Вы действительно должны понять эти проблемы перед запускомкодирование.Отладка многопоточных программ - это кошмар (недетерминизм, heisenbugs ).

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