问题在于:
我想写一个创建10个线程的短程序,每个程序打印一个通过指针传递给线程函数的“id”.
该计划的完整代码如下:
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- struct params {
- pthread_mutex_t mutex;
- int id;
- };
- typedef struct params params_t;
- void* hello(void* arg){
- int id;
- pthread_mutex_lock(&(*(params_t*)(arg)).mutex);
- id = (*(params_t*)(arg)).id;
- pthread_mutex_unlock(&(*(params_t*)(arg)).mutex);
- printf("Hello from %d\n",id);
- }
- int main() {
- pthread_t threads[10];
- params_t params;
- pthread_mutex_init (¶ms.mutex,NULL);
- int i;
- for(i = 0; i < 10; i++) {
- params.id = i;
- if(pthread_create(&threads[i],NULL,hello,¶ms));
- }
- for(i = 0; i < 10; i++) {
- pthread_join(threads[i],NULL);
- }
- return 0;
- }
假定的输出(按此顺序不必要):
- Hello from 0
- ....
- Hello from 9
实际结果是:
- Hello from 2
- Hello from 3
- Hello from 3
- Hello from 4
- Hello from 5
- Hello from 6
- Hello from 8
- Hello from 9
- Hello from 9
- Hello from 9
我试图将互斥锁放在hello()函数的不同位置,但它没有帮助.
我该如何实现线程同步?
编辑:假设结果不是必要的0 … 9它可以是这些数字的任意组合,但每一个应该只出现一次.
解决方法
有两个问题:
答:你正在使用锁,但主要不知道这个锁.
B.在这种情况下锁定是不够的.你想要的是线程通过相互发信号来协作(因为你希望main不会增加变量,直到一个线程说它完成打印它).您可以使用pthread_cond_t来实现此目的(Look here以了解有关此内容的更多信息).这归结为以下代码(基本上,我在代码中添加了适当的pthread_cond_t用法,以及一堆解释正在发生的事情的注释):
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- struct params {
- pthread_mutex_t mutex;
- pthread_cond_t done;
- int id;
- };
- typedef struct params params_t;
- void* hello(void* arg){
- int id;
- /* Lock. */
- pthread_mutex_lock(&(*(params_t*)(arg)).mutex);
- /* Work. */
- id = (*(params_t*)(arg)).id;
- printf("Hello from %d\n",id);
- /* Unlock and signal completion. */
- pthread_mutex_unlock(&(*(params_t*)(arg)).mutex);
- pthread_cond_signal (&(*(params_t*)(arg)).done);
- /* After signalling `main`,the thread could actually
- go on to do more work in parallel. */
- }
- int main() {
- pthread_t threads[10];
- params_t params;
- pthread_mutex_init (¶ms.mutex,NULL);
- pthread_cond_init (¶ms.done,NULL);
- /* Obtain a lock on the parameter. */
- pthread_mutex_lock (¶ms.mutex);
- int i;
- for(i = 0; i < 10; i++) {
- /* Change the parameter (I own it). */
- params.id = i;
- /* Spawn a thread. */
- pthread_create(&threads[i],¶ms);
- /* Give up the lock,wait till thread is 'done',then reacquire the lock. */
- pthread_cond_wait (¶ms.done,¶ms.mutex);
- }
- for(i = 0; i < 10; i++) {
- pthread_join(threads[i],NULL);
- }
- /* Destroy all synchronization primitives. */
- pthread_mutex_destroy (¶ms.mutex);
- pthread_cond_destroy (¶ms.done);
- return 0;
- }
我看到你正在尝试的例子是一个可能了解POSIX线程库的玩具程序.在现实世界中,我们都知道,即使不使用线程,也可以更快地完成.但你已经知道了.