2013-05-21 55 views
0

我有一个进程P和一个内核线程KT。我想同步P与KT的执行。 KT基本上是一个事件处理程序。但我的要求是KT不应该继续处理事件,如果P正在运行。所以我需要暂停P,然后继续在KT中进行事件处理并恢复P.因此,我的问题是,从KT开始,我该如何强制抢占P?稍后恢复时,我可以使用wake_up_process()。如何从另一个进程/内核线程中抢占一个进程?

对于调度进程,常用的技巧是将状态设置为TASK_INTERRUPTIBLE并调用schedule()。如果我保存了task_struct指针P,然后从KT开始安排P,我将P(而不是当前)的状态设置为TASK_INTERRUPTIBLE并调用调度?这是一个黑客,它会工作吗?你看到我失踪的任何干净的方式吗?

是否有一些信号可以发送P让它抢占?

+2

如果需要同步,为什么不使用同步原语(例如futex)而不是一些晦涩的技巧?在需要处理的时候阻止进程并将其唤醒。 – Damon

+0

'SIGSTOP'(因为你问的信号)是相似的 - 为什么应用这种黑客?使用多个线程意味着并行性(否则它并没有太大的意义 - 如果线程只能独占运行,那么也可以使用单个线程来处理所有事情)。所以,让消费线程(应用程序)阻塞在futex或eventfd上(如果你喜欢,可以通过epoll),而生产者(内核线程)在有需要时做出通知。它也不太容易失败。 – Damon

+0

谢谢达蒙。我重新设计使用锁而不是黑客。 – spa

回答

1

你不能做你在问什么。当然你可以设置状态为TASK_INTERRUPTIBLE从另一个进程/线程运行在相同或不同的CPU /内核上。但是你不能在另一个CPU /内核上调用schedule()(出于同样的原因,你不能在另一个CPU /内核上调用任何其他功能)。考虑到schedule()不会将CPU /内核ID作为参数,那么如何告诉它,core1应该重新计划?

这些类型的同步要求的另一种流行解决方案是使用实时优先级。这几乎和你提出的一样丑陋,但如果你的内核支持实时优先级,它实际上可以工作。这里的想法很简单,过程P比KT具有更高的优先级,并且它会在KT准备好运行时抢占KT。使用CPU亲和力将两个进程强制到相同的CPU /内核上(这很重要,否则无法工作!)。顺便说一下,在这种方法中没有任何真正的同步 - 当P和KT彼此相对运行时,您严格依赖RT优先级来强制执行。

我建议你接受Damon的建议并重新设计,因为没有真正干净的方式来做你想问的问题,但是有许多干净的方法来同步两个过程。

+1

如果你不能远程唤醒一个等待事件的线程,这意味着一个线程离开一个被另一个线程等待的互斥体,不能唤醒等待的线程,但肯定会发生(而且等待的线程不会“等待下一个计时器开始执行)。那么这工作怎么可能呢? – BeeOnRope

+0

@BeeOnRope - 你不能使用互斥信号发送一个事件(参见[这里](https://stackoverflow.com/questions/12551341/when-is-a-condition-variable-needed-isnt-a-mutex -enough/12569318#12569318))但您可以使用包含互斥锁的条件变量,但也使用信号灯式事件通知。而且,是的,你可以远程唤醒一个线程,但通过互斥量,信号量和条件变量,它不是**你正在调度线程,内核是_!使用线程状态和内核调度原语进行线程同步注定会失败。这是我的观点。 – slowjelj

+0

我的意思是一个核心上的代码在所有的时间触发另一个核心上的代码。例如,当一个线程离开一个“互斥体”,而另一个线程正在等待该互斥体时,该“其他线程”通常将开始在_another_ core上运行(因为刚刚离开该互斥体的代码仍在其核心中运行)。我不知道你为什么指的是事件或条件变量:我只是选择互斥量作为并发控制对象的最简单的例子,这同样适用于信号量,障碍,条件变量。 – BeeOnRope

相关问题