C Linux内核互斥体
我正在阅读“Linux设备驱动程序第三版”,这是关于并发性和竞争条件的一章。有一个例子我不完全理解;他们讨论的是内核编程中的一种常见模式,当需要在当前线程之外启动活动(fo rexample、新内核线程或用户进程、对现有进程的请求或基于硬件的操作)时,等待该活动完成。不太有效的解决方案示例如下:C Linux内核互斥体,c,linux,multithreading,kernel,C,Linux,Multithreading,Kernel,我正在阅读“Linux设备驱动程序第三版”,这是关于并发性和竞争条件的一章。有一个例子我不完全理解;他们讨论的是内核编程中的一种常见模式,当需要在当前线程之外启动活动(fo rexample、新内核线程或用户进程、对现有进程的请求或基于硬件的操作)时,等待该活动完成。不太有效的解决方案示例如下: struct semaphore sem; init_MUTEX_LOCKED(&sem); start_external_task(&sem); down(&sem); 然后
struct semaphore sem;
init_MUTEX_LOCKED(&sem);
start_external_task(&sem);
down(&sem);
然后,他们建议外部任务在其工作完成时调用(&sem)
我不明白为什么我们不能这样做:
struct semaphore sem;
down(&sem);
start_external_task(&sem);
为什么必须在锁定状态下创建互斥体,然后在任务启动后获取互斥体
期待您的来信!谢谢。当您调用down()时,您的线程将阻塞,直到另一个线程发出信号。由于另一个线程尚未启动,该线程将无限期阻塞。这就是为什么您需要首先启动线程,然后调用down()来阻塞,直到线程完成
如果线程在您调用down()之前完成,那没关系,因为信号量将发出信号,down()将简单地清除信号并返回。在第一个示例中,down(&sem)将等待外部_任务调用(&sem),并有效地暂停主线程,直到任务完成。
在您的代码中,down()将永远锁定主线程,因为还没有要调用的任务()调用:
init_MUTEX_LOCKED(&sem);
在“互斥模式”下创建一个初始化为0的新信号量。这意味着对down()
的调用将被阻止。相应的呼叫:
init_MUTEX(&sem);
将创建一个初始化为1的信号量
在第一个示例中,将信号量初始化为0,创建外部_任务并调用down()
阻塞,直到任务调用up()
在第二个示例中,您不初始化信号量,而是调用down()
阻止执行,并且没有运行可以调用up()
取消阻止您的外部任务。因此,无法调用创建外部任务
顺便说一句,在内核版本2.6.37中,使用init_MUTEX_LOCKED初始化信号量的过程已经被删除。+1,但是我认为使用术语
信号量
而不是互斥
会更好。信号量:可以由任何线程向上/向下。互斥体:拥有所有权,只有锁所有者线程才能启动互斥体。在这种情况下,我们需要使用信号量,因为它的目的是线程之间的通信…@Vojita:我同意。我使用术语互斥是因为问题将信号量称为互斥。