Linux 内核互斥锁

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4757852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:34:29  来源:igfitidea点击:

Linux kernel mutexes

clinuxmultithreadingkernel

提问by Mark

I am reading "Linux device drivers 3rd edition", the chapter about concurrrency and race conditions. There is an example I don't completely understand; they are talking about the a common pattern in kernel programming, when one needs to initiate activity (fo rexample, new kernel thread or user process, request for existing process, or hardware based action) outside of the current thread, wait for that activity to complete. The example of not very effective solution is:

我正在阅读“Linux 设备驱动程序第 3 版”,有关并发和竞争条件的章节。有一个我不完全理解的例子;他们谈论的是内核编程中的一种常见模式,当需要在当前线程之外启动活动(例如,新内核线程或用户进程、请求现有进程或基于硬件的操作)时,等待该活动完全的。不是很有效的解决方案的例子是:

struct semaphore sem;
init_MUTEX_LOCKED(&sem);
start_external_task(&sem);
down(&sem);

Then they suggest the external task to call up(&sem) when its work is done.

然后他们建议外部任务在其工作完成后调用(&sem)。

I don't understand why can't we do it this way:

我不明白为什么我们不能这样做:

struct semaphore sem;
down(&sem);
start_external_task(&sem);

Why is is necessary to create mutex in locked state and then acquire the mutex after the task has been started?

为什么需要在锁定状态下创建互斥锁,然后在任务启动后获取互斥锁?

Looking forward to hearing from you! Thanks.

期待您的回音!谢谢。

回答by Antoine Aubry

When you call down(), your thread will block until another thread signals the semaphore. Since the other thread is not yet started, the thread will block indefinitely. That's why you need to start the thread first, and then call down() to block until the thread finishes.

当您调用 down() 时,您的线程将阻塞,直到另一个线程向信号量发出信号。由于另一个线程尚未启动,该线程将无限期阻塞。这就是为什么你需要先启动线程,然后调用 down() 阻塞直到线程完成。

If the thread finishes before you call down(), that's ok, because the semaphore will be signaled and down() will simply clear the signal and return.

如果线程在您调用 down() 之前完成,那没关系,因为信号量将被发出信号并且 down() 将简单地清除信号并返回。

回答by blaze

In first example down(&sem) will wait for external_task to call up(&sem) and effectively pause main thread until task completion. In your code down() will lock main thread forever since there is no task yet to call up()

在第一个示例中 down(&sem) 将等待 external_task 调用 up(&sem) 并有效地暂停主线程直到任务完成。在您的代码中 down() 将永远锁定主线程,因为还没有调用 up() 的任务

回答by James Greenhalgh

The call:

电话:

init_MUTEX_LOCKED(&sem);

Creates a new semaphore in "mutex mode" initialised to 0. This means that a call to down()will block. A corresponding call:

在初始化为 0 的“互斥模式”中创建一个新的信号量。这意味着对 的调用down()将被阻塞。相应的调用:

init_MUTEX(&sem);

Would create a semaphore initialised to 1.

将创建一个初始化为 1 的信号量。

In the first example you initialise the semaphore to 0, you create your external_task and you call down()blocking until your task calls up().

在第一个示例中,您将信号量初始化为 0,您创建了 external_task 并调用了down()阻塞,直到您的任务调用up().

In the second example you don't initialise your semaphore, call down()blocking execution, and have no external_task running which can call up()to unblock you. The call to create external_task is thus never reached.

在第二个示例中,您没有初始化信号量,没有调用down()阻塞执行,并且没有运行可以调用up()解除阻塞的external_task 。因此永远不会调用创建 external_task。

Incidentally, the process of initialising the semaphore with init_MUTEX_LOCKED has been removed in kernel version 2.6.37.

顺便提一下,在内核版本 2.6.37 中删除了使用 init_MUTEX_LOCKED 初始化信号量的过程。