简体   繁体   English

如何避免由睡眠线程锁定(拥有)的互斥锁上的许多线程锁定?

[英]How can I avoid lock of many threads on mutex which locked (owned) by thread which sleep?

This problem known as Convoying : all other threads have to wait if a thread holding a lock is descheduled due to a time-slice interrupt or page fault. 这个问题称为Convoying :如果由于时间片中断或页面错误而对持有锁的线程进行了调度,则所有其他线程都必须等待。 https://en.wikipedia.org/wiki/Lock_(computer_science)#Disadvantages https://zh.wikipedia.org/wiki/Lock_(computer_science)#缺点

As known if thread-1 locks the std::mutex and occurs switch of thread-1, and if at this time many threads (2, 3, 4 ...) want to lock this mutex, then all these threads will locked and will be waiting for switch-on thread-1. 众所周知,如果线程1锁定了std::mutex并发生了线程1的切换,并且如果此时许多线程(2、3、4 ...)想要锁定该互斥锁,则所有这些线程都将被锁定并将等待打开线程1。

The solution to this is to use lock-free algorithms. 解决方案是使用无锁算法。 But if requre to use a mutex, that is some solution to avoid such a situation? 但是,如果需要使用互斥锁,那是避免这种情况的解决方案吗?

  1. How can I find out in advance for 100 cycles before the imminent switching of thread? 在即将进行线程切换之前,如何预先找出100个周期?

  2. Or how can I raise an exception in advance for 100 cycles before switching the flow on Linux x86_64? 或者如何在Linux x86_64上切换流之前提前100个周期引发异常?

  3. Or how can I to make continue work of thread for some time (100 cycles)? 或者如何使线程继续工作一段时间(100个周期)?

UPDATE: 更新:

I have 20 CPU Cores, and my program have 40 threads divided by 2 parts: 我有20个CPU内核,我的程序有40个线程,该线程除以2部分:

  • Part-1 - 20 threads use 1-st shared resource protected by std::mutex mtx1 第1部分 -20个线程使用受std::mutex mtx1保护的第一共享资源
  • Part-2 - 20 threads use 2-nd shared resource protected by std::mutex mtx2 第2部分 -20个线程使用受std::mutex mtx2保护的第二个共享资源

It is known that the operating system gives each thread a certain quantum of time to work after which lulls him, and gives the vacant core of the next thread that will run the same time slot. 众所周知,操作系统会为每个线程分配一定的工作时间,在此之后会使他平静下来,并为下一个将在同一时隙运行的线程提供空闲的内核。

Part-1: Sometimes, not often, but this case is critical for me, happen that 1 of 20 threads do mtx1.lock() then start work with shared resource and then OS switch-off (puts to sleep) this thread before done mtx1.unlock() - because expired quant of time which allocated by OS to this thread and operating system decided to makes sleep this thread. 第1部分:有时(不是经常),但这种情况对我来说很关键,发生20个线程中的1个执行mtx1.lock()然后开始使用共享资源,然后在完成之前先关闭该线程的操作系统(使系统进入睡眠状态) mtx1.unlock() -因为操作系统分配给该线程的时间已到期,操作系统决定让该线程进入睡眠状态。 And OS switch-on this thread only after ~1 - 10ms (30 000 000 cycles). 并且OS仅在〜1-10ms(3000万个周期)之后才打开该线程。 During this time 19 other threads of Part-1 at least once try to get a shared resource each of 10 usec ( 30 000 cycles), but mtx1 is busy. 在这段时间内,Part-1的其他19个线程至少一次尝试获取10 mtx1 (30000个周期)中的每个共享资源,但是mtx1忙。

Then each of 19 threads of Part-1 begins to fall asleep, and vacated CPU-cores are occupied by threads from Part-2 . 然后, 第1部分的19个线程中的每个线程开始入睡,腾出的CPU内核被第2部分中的线程占用。 OS see that all cores are busy and don't wake thread of Part-1 . 操作系统发现所有内核都在忙,并且没有唤醒Part-1的线程。

This case occurs not often, but when this occurs then Part-1 (20 threads) freezes a whole 1-10 milliseconds (30 000 000 cycles), which is very unacceptably for the task. 这种情况并不经常发生,但是当发生这种情况时,Part-1(20个线程)将冻结整个1-10毫秒(3000万个周期),这对于任务来说是非常不可接受的。

How do that never been a situation with a delay of Part-1 more than 10 microseconds (30 000 cycles)? 第一部分延迟超过10微秒(3万个周期)的情况怎么可能呢?

The point of lock-free or near-lock-free designs is that if you do need a mutex for something, then that something would be rare and hence you would have a low probability of any two threads hitting the same mutex at the same time. 无锁或近锁设计的要点是,如果确实需要互斥锁,那么某些东西将很少见,因此,任何两个线程同时命中同一互斥锁的可能性很小。 。

Your explanation of your design and the countermeasures you are prepared to take sound like you think there is a high probability that all the threads will hit the mutex -- so either your thinking is wrong or your design is wrong. 您对设计的解释和准备采取的对策听起来像您认为所有线程都很有可能会碰到互斥锁-因此您的想法是错误的或设计是错误的。

There is nothing you can do to read the mind of the scheduler, but as discussed here there is something you can do that may influence the way your thread is scheduled -- however I would recommend against playing around with anything like that. 您无法做任何事情来了解调度程序的思想,但是正如此处所讨论的您可以做些可能会影响您的线程 调度方式的事情-但是我建议您不要尝试任何类似的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM