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