【问题标题】:Linux Scheduling: OS vs "virtual"Linux 调度:操作系统与“虚拟”
【发布时间】:2012-06-04 06:15:01
【问题描述】:
如何在 c 下的 linux fedora 中实现多线程单进程模型,其中单个调度程序用于“主”核心读取 i/o 可用性(例如 tcp/ip、udp)然后具有单线程- per-core(从init开始),“执行线程”,解析数据然后更新少量信息更新到共享内存空间(我的理解是pthreads在单个进程下共享数据)。
我相信我的选择是:
Pthreads 或 linux OS 调度程序
我有一个简单的模型,包括启动一定数量的这些执行线程一个单个调度程序线程。
当我知道我可以使用这种模型时,人们能想到的最佳解决方案是什么。
【问题讨论】:
标签:
c
linux
multithreading
scheduling
【解决方案1】:
完成 Benoit 的回答,为了在您的主线程和工作线程之间进行通信,您可以使用条件变量。工人会做这样的事情:
while (true)
{
pthread_mutex_lock(workQueueMutex);
while (workQueue.empty())
pthread_cond_wait(workQueueCond, workQueueMutex);
/* if we get were then (a) we have work (b) we hold workQueueMutex */
work = pop(workQueue);
pthread_mutex_unlock(workQueueMutex);
/* do work */
}
和主人:
/* I/O received */
pthread_mutex_lock(workQueueMutex);
push(workQueue, work);
pthread_cond_signal(workQueueCond);
pthread_mutex_unlock(workQueueMutex);
这将唤醒一项空闲工作以立即处理请求。如果没有可用的工作人员,工作将被出列并稍后处理。
【解决方案2】:
修改 Linux 调度程序是一项艰巨的工作。我会忘记它。通常首选 Pthread。如果我理解得很好,您想要一个专用于控制计划的核心,以及一个专用于数据计划处理的其他核心池吗?然后从您的主线程创建一个线程池,并使用pthread_setaffinity_np(...) 为这些从属线程设置核心亲和性。
一个进程的线程确实共享相同的地址空间,并且该进程的任何线程都可以访问全局变量。
【解决方案3】:
在我看来,您有一个 producer-consumer problem 版本,其中单个消费者聚合了 n 生产者的结果。这是一个非常标准的问题,所以我绝对认为pthread 对你来说已经足够了。你不需要去搞乱调度程序。
作为答案的状态之一,像here 描述的线程安全队列非常适合此类问题。您最初产生一堆线程的想法是个好主意。您似乎担心线程共享全局状态的能力会给您带来问题。如果您将共享状态保持在最低限度并使用合理的锁定规则,我认为这不是问题。只要您负责任地共享状态就可以了。
最后,除非您真的知道自己在做什么,否则我建议您不要手动弄乱线程关联。只需生成线程并让调度程序处理线程运行的时间和核心。要优化的是您使用的线程数。如果其他线程正在运行,每个内核一个可能实际上并不是最快的方法。
【解决方案4】:
一般来说,这或多或少正是 posix select 和 linux 特定的 epoll 函数的用途。