Linux内核互斥体

时间:2011-01-21 10:45:52

标签: c linux multithreading kernel

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

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

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

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

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

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

期待您的回音!感谢。

3 个答案:

答案 0 :(得分:10)

当你调用down()时,你的线程将阻塞,直到另一个线程发出信号信号。由于其他线程尚未启动,线程将无限期地阻塞。这就是为什么你需要先启动线程,然后调用down()来阻塞直到线程结束。

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

答案 1 :(得分:3)

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

答案 2 :(得分:1)

电话:

init_MUTEX_LOCKED(&sem);

以“互斥模式”初始化为0创建新信号量。这意味着对down()的调用将被阻止。相应的电话:

init_MUTEX(&sem);

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

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

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

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