Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何从另一个进程/内核线程抢占一个进程?_Linux_Linux Kernel_Kernel - Fatal编程技术网

Linux 如何从另一个进程/内核线程抢占一个进程?

Linux 如何从另一个进程/内核线程抢占一个进程?,linux,linux-kernel,kernel,Linux,Linux Kernel,Kernel,我有一个进程p和一个内核线程KT。我想将P的执行与KT同步。KT基本上是一个事件处理程序。但我的要求是,如果P正在运行,KT不应该继续处理事件。所以我需要暂停P,然后继续在KT中进行事件处理,然后恢复P。所以我的问题是,从KT开始,我如何强制抢占P?为了以后继续,我可以使用wake\u up\u process() 对于调度进程,常用的技巧是将状态设置为TASK_Interruptable并调用schedule()。如果我保存了P的task_struct指针,然后从KT到schedule out

我有一个进程p和一个内核线程KT。我想将P的执行与KT同步。KT基本上是一个事件处理程序。但我的要求是,如果P正在运行,KT不应该继续处理事件。所以我需要暂停P,然后继续在KT中进行事件处理,然后恢复P。所以我的问题是,从KT开始,我如何强制抢占P?为了以后继续,我可以使用wake\u up\u process()

对于调度进程,常用的技巧是将状态设置为TASK_Interruptable并调用schedule()。如果我保存了P的task_struct指针,然后从KT到schedule out P,我将P的状态(而不是current)设置为task_INTERRUPTIBLE并调用schedule,它会工作吗?这是一个黑客,它会工作吗?你能看到我错过的任何干净的方式吗


有什么信号我可以发送给p要求它抢先吗?

你不能做你要求的事情。当然,您可以将状态设置为TASK_INTERRUPTIBLE,该状态来自运行在同一个或不同CPU/内核上的另一个进程/线程。但是您不能在另一个CPU/核心上调用schedule()(出于同样的原因,您不能在另一个CPU/核心上调用任何其他函数)。考虑到调度()不将CPU/CARID作为一个参数,那么您如何告诉CORE1应该重新调度?< /P> 对于这些类型的同步需求,另一种流行的解决方案是使用实时优先级。这几乎和您提出的一样难看,但如果您有一个支持实时优先级的内核,它实际上可以工作。这里的想法很简单,进程P的优先级比KT高,当它准备好运行时,它将抢占KT。使用CPU关联将两个进程强制放在同一个CPU/核心上(这很重要,否则它将无法工作!)。顺便说一句,在这种方法中没有任何真正的同步——当P和KT相对运行时,您严格依赖于RT优先级来执行


我建议您采纳Damon的建议并重新设计,因为没有真正干净的方法来完成您的要求,但有许多干净的方法来同步两个进程。

如果需要同步,为什么不使用同步原语(如futex)而不是一些模糊的技巧?当有事情要处理时,让进程阻塞并唤醒它。
SIGSTOP
(因为你要求信号)是类似的——为什么要应用这样的黑客?使用多个线程意味着并行性(否则就没有多大意义了——如果线程只以独占方式运行,那么您也可以使用单个线程来完成所有任务)。因此,让futex或eventfd上的消费线程(应用程序)阻塞(如果您愿意,可以通过epoll)和生产者(内核线程)在有事情要做时通知。它也不太容易失败。谢谢Damon。我重新设计了使用锁而不是黑客。如果你不能远程唤醒一个等待事件的线程,这意味着一个线程离开了另一个线程正在等待的互斥锁,就不能唤醒等待的线程,但肯定会这样做(等待的线程不会等到下一个计时器开始执行)。那么这怎么可能呢?@BeeOnRope-您不能使用互斥来向事件发送信号(请参阅),但您可以使用一个条件变量,该变量包括互斥,但也使用信号量样式的事件通知。当然,您可以远程唤醒线程,但是,通过互斥体、信号量和条件变量,调度线程的不是您,而是内核!使用线程状态和内核调度原语进行线程同步注定会失败。这就是我的观点。我的意思是,一个核心上的代码总是触发另一个核心上的代码。例如,当一个线程离开了一个
互斥体,而另一个线程正在等待该互斥体时,“另一个线程”通常会开始在另一个内核上运行(因为刚刚离开互斥体的代码仍在其内核上运行)。我不知道你为什么要提到事件或条件变量:我刚刚选择了互斥作为并发控制对象的最简单示例,这同样适用于信号量、屏障、条件变量等等。共同的主题是,在一个内核上运行的代码触发另一个内核上的代码是非常常见的。如果我明白你的意思,那就不会发生。是的,当然是内核做的,但是我有没有声明其他的呢?用户空间代码调用内核,内核根据需要唤醒另一个内核上的代码,通常通过IPI或
监视器
/
mwait
类型构造。要么你不明白我在说什么,要么我不明白你在说什么。但请指出我说过的一个核心上的代码不能触发另一个核心上的代码的地方。你似乎在反驳我从未提出过的观点。我知道互斥锁是如何工作的,但是谢谢你的复习。