【发布时间】:2020-12-01 14:36:26
【问题描述】:
我一直在编写在 C 中使用 pthread 库的代码。代码执行以下操作:
- 主要创建两个线程,每个线程都有自己的线程例程(函数)
- 一个线程(线程 1)生成一个随机数并将其分配给全局变量 x
- 然后另一个线程(线程2)基本上打印全局变量的值
- 这个生成并打印 x 的随机值的操作重复了 5 次
预期输出:
generator thread >> x = 5
printer thread >> x = 5
generator thread >> x = 9
printer thread >> x = 9
generator thread >> x = 7
printer thread >> x = 7
generator thread >> x = 3
printer thread >> x = 3
generator thread >> x = 2
printer thread >> x = 2
但是,输出以随机顺序出现,有时打印机首先执行,或者其中一个线程在另一个线程执行之前多次执行。
例如:
$ ./mutex.out
generator >> x = 7
generator >> x = 10
generator >> x = 4
generator >> x = 7
generator >> x = 10
printer >> x = 7
printer >> x = 10
printer >> x = 10
printer >> x = 10
printer >> x = 10
$ ./mutex.out
printer >> x = 0
printer >> x = 0
printer >> x = 0
printer >> x = 0
printer >> x = 0
generator >> x = 9
generator >> x = 2
generator >> x = 1
generator >> x = 3
generator >> x = 7
我为这个问题写的代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NUMTHRDS 2
pthread_t t [ NUMTHRDS];
pthread_mutex_t m1, m2;
int x = 0;
void *thread1(void *arg){
for(int i = 0 ; i < 5 ; i++){
pthread_mutex_lock(&m2);
pthread_mutex_lock(&m1);
x = (rand() % 10) + 1; // generates a random number between 1 and 10
printf("generator >> x = %d\n" , x);
pthread_mutex_unlock(&m1);
pthread_mutex_unlock(&m2);
}
}
void * thread2(void * arg){
for(int i = 0 ; i < 5 ; i++){
pthread_mutex_lock(&m1);
pthread_mutex_lock(&m2);
printf("printer >> x = %d\n" , x);
pthread_mutex_unlock(&m2);
pthread_mutex_unlock(&m1);
}
}
int main(void)
{
srand(time(NULL));
pthread_mutex_init(&m1, NULL);
pthread_mutex_init(&m2, NULL);
pthread_create(&t[1], NULL, thread1, NULL);
pthread_create(&t[0], NULL, thread2, NULL);
pthread_mutex_destroy(&m1);
pthread_mutex_destroy(&m2);
pthread_exit(NULL);
return 0;
}
我的问题是如何正确使用互斥锁,以便在不使用其他任何东西的情况下保持这两个线程之间的顺序。
【问题讨论】:
-
主线程(主程序)必须使用 pthread_join() 等待线程结束,否则整个程序可能在线程有机会做某事之前完成。所以调用 pthread_join() 在销毁互斥体之前等待线程结束。
-
与互斥锁同步并不能保证顺序执行。您应该计划使用条件变量(即 pthread_cond_wait/signal())来唤醒线程
-
这是由 pthread_exit(NULL) 完成的,我相信这会强制主线程等待程序中的所有线程完成
-
是的,但是您之前销毁了互斥锁,因此线程可能会使用已销毁的互斥锁...
-
你很幸运代码没有死锁。如果
thread1锁定m2和thread2已经有m1但没有锁定m2,thread1和thread2会死锁。
标签: c multithreading pthreads mutex