我有一个多线程C / C ++程序,可以非常频繁地为读写请求提供服务。出于同步目的,我使用了互斥锁进行锁定和解锁。所有读写线程在执行操作之前都会获得锁定。如果一个线程获得锁定并且在它释放锁定之前会发生什么?线程会恢复执行还是我必须手动处理它?</ p>
答案 0 :(得分:3)
用户端锁定(包括互斥锁)不会阻止中断。这很重要,因为通常可以使用互斥锁来保护读取磁盘上的文件,或者保护从网络接收数据包等,其结果依赖于中断。
实质上,如果有中断,则“无”。中断由操作系统处理,就像任何其他时间一样。在这种情况下,程序不需要做任何事情,如果发生这种情况,只需花费几微秒或几毫秒就可以完成任务。
某些内核端锁(例如SpinLocks)确实会阻止(在该处理器核心上)中断,以确保在此过程中不会调度其他进程/线程。在这些情况下,内核可以使用哪些函数也存在限制 - 例如,在此期间无法调用阻塞函数(如睡眠,等待事件或文件读取或文件写入)这一次,因为这可能导致内核锁定。
答案 1 :(得分:1)
线程最终将恢复执行,它可能在内核服务中断后立即发生,或者内核调度程序可能决定调度另一个准备运行的线程。如果被中断的线程获得了严重争议的锁,那么尝试获取该锁的其他线程将阻塞(或旋转,旋转然后阻塞,具体取决于互斥锁的实现),直到再次调度被中断的线程为止,结束受锁定保护的关键部分,并将其解锁。
在需要接近实时性能的系统中,需要仔细调整以将关键线程分配给它们自己的内核(cpu亲和性)并将中断映射到其他内核。此外,还要特别注意锁的使用,有时使用无锁的算法。
答案 2 :(得分:0)
线程具有锁定的事实不受信号的影响。如果线程有锁并接收信号,则不会发生任何特殊情况。 实际上,信号和线程不能很好地混合,因为信号的设计考虑了过程。那是因为你无法知道哪个线程会获得信号。处理这种情况的正确方法是使用一个特定的线程来管理信号,例如阻止每个线程中的所有信号而不是一个线程,其中只有负责处理信号。这是处理具有线程的软件中的信号的正确方法。