具有pthread功能的静态存储

时间:2012-02-29 11:38:53

标签: c linux pthreads

我正在练习一些多线程程序,但我无法弄清楚这个输出背后的逻辑。

#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 个答案:

答案 0 :(得分:4)

变量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);
}

如果您不使用互斥锁,则永远不会确定以获得您认为应该获得的输出。

答案 1 :(得分:3)

有几本关于多线程的好书。我觉得很有意思Butenhof's "Programming with Posix threads",但最近出现的书很多。

您是否在网上阅读了其中任何内容或pthreads tutorial好文章?

基本上,每个程序源代码线程可能无法像您期望的那样直观地查看内存。 (cache coherencemulti-processingmemory modelC11 ...)

实际上,对线程之间共享的数据的任何访问都应受synchronization原语的保护,例如mutexesrwlocks

在开始编码之前,您真的应该了解这些问题。调试多线程程序是一场噩梦(非确定性,heisenbugs)。