如何在 C 中使用互斥体
我对 C 中使用多个互斥体感到困惑。
int main() {
pthread_t thread1;
char *message1 = "Thread 1";
int r;
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_mutex_lock(&mutex1);
r = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
printf("Parent 1\n");
pthread_mutex_lock(&mutex2);
printf("Parent 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
pthread_join( thread1, NULL);
printf("Thread 1 returns: %d\n",r);
return 0;
}
void *print_message_function( void *str ) {
pthread_mutex_lock(&mutex1);
char *message;
message = (char *) str;
printf("Child 1 received message: %s \n", message);
pthread_mutex_lock(&mutex2);
printf("child 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
输出是
Parent 1
Parent 2
Child 1 received message: Thread 1
child 2
Thread 1 returns: 0
我想要的
Parent 1
Child 1 received message: Thread 1
Parent 2
child 2
Thread 1 returns: 0
I am confused about use of multiple mutexes in C.
int main() {
pthread_t thread1;
char *message1 = "Thread 1";
int r;
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_mutex_lock(&mutex1);
r = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
printf("Parent 1\n");
pthread_mutex_lock(&mutex2);
printf("Parent 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
pthread_join( thread1, NULL);
printf("Thread 1 returns: %d\n",r);
return 0;
}
void *print_message_function( void *str ) {
pthread_mutex_lock(&mutex1);
char *message;
message = (char *) str;
printf("Child 1 received message: %s \n", message);
pthread_mutex_lock(&mutex2);
printf("child 2\n");
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
return NULL;
}
output is
Parent 1
Parent 2
Child 1 received message: Thread 1
child 2
Thread 1 returns: 0
what i want is
Parent 1
Child 1 received message: Thread 1
Parent 2
child 2
Thread 1 returns: 0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您调用
pthread_create
时,您已经锁定了mutex1
。这意味着调用 pthread_mutex_lock(&mutex1); 的每个其他线程都将等待互斥体解锁。这就是当您创建第二个线程时发生的情况:互斥体 1 已经被锁定,因此第二个线程无法进入临界区,而是需要等待互斥体被解锁。这发生在main
函数的末尾。您需要重新组织代码才能获得所需的输出。
但是,要获得这样的结果,您应该检查同步系统,例如信号量 或 条件变量;它们将提供一种更清晰、更简单的线程同步方法。
您还可以查看本教程: POSIX 线程编程
使用信号量的简单解决方案(未经测试,但它应该有效):
When you call
pthread_create
you have already lockedmutex1
. That means that every other thread that callspthread_mutex_lock(&mutex1);
will wait for the mutex to be unlocked. That is what happen when you create a second thread:mutex1
is already locked, so the second thread cannot enter the critical section but need to wait for the mutex to be unlocked. That happens at the end of themain
function.You'll need to reorganize your code to get the output you desire.
However, to obtain such a result you should check synchronization systems, such semaphores or condition variables; they will provide a clearer and easier way to synchronize threads.
You may also check this tutorial: POSIX Threads Programming
A simple solution using semaphores (not tested, but it should work):
互斥体本身并不适合执行您想要的那种紧密互锁的执行 - 它们的正常用途是保护对共享数据结构的访问。这是因为它们的目的是说“事情 A 不应该与事情 B 同时发生”,但它们没有说明事情 A 或事情 B 是先发生还是后发生。 。
您可以使用互斥体和条件变量,但在这种情况下,您的问题与 pthreads Barrier 对象最匹配:
请注意,通常不尝试以这种方式紧密互锁线程的执行 -实际上,您已经煞费苦心地确保线程根本不会并行执行,这首先就是线程的全部意义。如果您发现自己在实际项目中这样做,则表明您应该仔细重新考虑您的设计。
Mutexes alone aren't suitable for performing the kind of closely-interlocked execution that you want - their normal use is for protecting access to a shared data structure. This is because they're designed for saying "Thing A shouldn't happen at the same time as Thing B", but they don't say anything about whether Thing A or Thing B happens first or second.
You could use mutexes and condition variables, but in this case your problem is most closely matched by a pthreads Barrier object:
Note that it is not usual to try to tightly interlock the execution of threads in this way - really, you've gone to great pains to ensure that the threads don't execute in parallel at all, which is the whole point of threads in the first place. If you find yourself doing this in a real project, it's a sign that you ought to carefully re-think your design.
我认为您需要尽快解锁
mutex1
。您在printf("Parent 2\n");
之后解锁它,因此 thread1 仍处于锁定状态,等待pthread_mutex_lock(&mutex1);
。当 thread1 启动时,它的第一步是在等待 mutex1 上的互斥(线索就在名称中)锁定时进行锁定。所以暂停了。
然后你 :
I think you need to unlock
mutex1
sooner. You unlock it after theprintf("Parent 2\n");
so thread1 is still locked waiting forpthread_mutex_lock(&mutex1);
.When thread1 starts it's first step is to lock while it waits for mutual exclusion (clue's in the name) lock on mutex1. So it's paused.
Then you :