2014-03-25 57 views
1

这是互斥锁的经典示例。我不知道为什么下面的代码不起作用,即。它不会每次都打印“ctr = 0”(但是,例如,ctr = 535)。两个线程,第一个添加第二个替代品

int ctr; 
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; 

void * add (void * arg_wsk) 
{ 
     int i; 
     for (i = 0; i < 100000; i++) { 
       pthread_mutex_lock (&m); 
       ctr++; 
       pthread_mutex_unlock (&m); 
     } 
     return(NULL); 
} 

void * sub(void * arg_wsk) 
{ 
     int i; 
     for (i = 0; i < 100000; i++) { 
       pthread_mutex_lock (&m); 
       ctr--; 
       pthread_mutex_unlock (&m); 
     } 
     return(NULL); 
} 
int main() 
{  
     pthread_t tid1, tid2; 
     int i; 
     void *res; 
     ctr = 0; 
     pthread_mutex_init(&m, NULL); 

     pthread_create(&tid1, NULL, add, NULL); 
     pthread_detach(tid1); 

     pthread_create(&tid2, NULL, sub, NULL); 
     pthread_detach(tid2); 

     pthread_join(tid1, &res); 
     pthread_join(tid2, &res); 

     pthread_mutex_destroy(&m); 
     printf("ctr = %d", ctr); 
     pthread_exit(NULL); 
} 

你能指点我正确的方向吗?

此外,stackoverflow告诉我提供一些更多的细节,我的问题主要是代码。但是我真的不知道在这里写什么,我只是希望当我有更多的声望时这条消息会消失。

+0

未能检查任何pthread库返回值意味着您可能忽略了一个重要的错误。 – kmarsh

回答

4

我认为你滥用POSIX API。如果你分离线程,你不应该加入它们。删除分离,看看这是否改善了事情。我想你会看到main()现在阻塞,直到线程完成。

还要注意,从的链接加入通话

ESRCH No thread could be found corresponding to that specified by the 
      given thread ID. 

如果你幸运的话,你会打这个。如果你不幸运,疯狂的事情会发生。不要在同一个线程上混合分离和加入调用。

https://computing.llnl.gov/tutorials/pthreads/#Joining

+1

是的,它为我修好了。 – kmarsh

+0

解决了这个问题,您还应该研究如何将参数传递给线程。如果你在'main()'中使ctr成为一个局部变量,并将调用改为'pthread_create(&tid1,NULL,add,&ctr)',我会将其视为更具可读性的代码。 – Trygve

+0

我错误地认为“分离”意味着什么。谢谢。 – Matt

1

您的计数器ctr的值取决于两个线程完成其完整的执行。

根据pthread_detach(3)

一旦一个线程已被分离,它不能与 在pthread_join接合(3)或再次作出可连接。

如果您从程序中删除pthread_detach调用,您将获得预期的输出。

此外,考虑明确创建您的线程可连接(或分离)的便携性。

+0

你是对的,但除了“不要脱离线程”之外,还有其他方法可以解决问题。这实际上只不过是线程同步的另一点,其中pthread_join(如果可能,在这种情况下不可能如您所指出的那样)是一种同步形式。 – mah

相关问题