Linux进程还是线程,Linux时间分割进程还是线程?

一位教授曾经在课堂上告诉我们,Windows,Linux,OS X和UNIX在线程上而不是在进程上扩展,因此,即使在单个处理器上,线程也可能会使应用程序受益,因为应用程序将在CPU上获得更多时间。

我试着用我的机器上的以下代码(它只有一个CPU)。

#include #include #include pthread_t xs[10]; void *nop(void *ptr) { unsigned long n = 1UL << 30UL; while(n--); return NULL; } void test_one() { size_t len = (sizeof xs) / (sizeof *xs); while(len--) if(pthread_create(xs+len, NULL, nop, NULL)) exit(EXIT_FAILURE); len = (sizeof xs) / (sizeof *xs); while(len--) if(pthread_join(xs[len], NULL)) exit(EXIT_FAILURE); } void test_two() { size_t len = (sizeof xs) / (sizeof *xs); while(len--) nop(NULL); } int main(int argc, char *argv[]) { test_one(); // test_two(); printf("done\n"); return 0; }

两个testing在速度方面是相同的。

real 0m49.783s user 0m48.023s sys 0m0.224s

real 0m49.792s user 0m49.275s sys 0m0.192s

这个我想,“哇,线程吮吸”。 但是,在四台处理器的大学服务器上重复testing接近四倍的速度。real 0m7.800s user 0m30.170s sys 0m0.006s

real 0m30.190s user 0m30.165s sys 0m0.004s

当我解释我的家用机器的结果时,我可以忽略一些东西吗?

为了理解内部任务/线程…让我们看看这个玩具内核代码…

结构regs {

int eax,ebx,ecx,edx,es,ds,gs,fs,cs,ip,flags;

struct tss * task_sel;

}

结构线程{

结构regs * regs;

int parent_id;

struct thread * next;

}

结构任务{

结构regs * regs;

int * phys_mem_begin;

int * phys_mem_end;

int *文件句柄;

优先

int * num_threads;

诠释量子

整数持续时间

int start_time,end_time;

int parent_id;

结构线程* task_thread;

/ * ... * /

struct task * next;

}

想象一下,内核为结构task (这是一个链表)分配内存,仔细观察quantum领域,即基于priority领域的处理器时间的时间片。 总是会有一个ID 0的任务,它不会睡觉,只是空闲,也许发出nops(没有OPerationS)…调度器围绕广告nauseum旋转,直到无限(即电源被拔下),如果quantum场决定任务运行20ms,设置start_time和end_time + 20ms,当end_time启动时,内核将cpu寄存器的状态保存到regs指针中。 进入链中的下一个任务,将cpu寄存器从指针加载到regs并跳转到指令中,设置量程和持续时间,当持续时间达到零时,继续下一个有效的上下文切换。这是什么使它在一个CPU上同时运行的错觉。

现在看看thread结构,它是task结构中的线程链接列表。 内核为该任务分配线程,为该线程设置CPU状态,并跳转到线程中…现在内核必须管理线程以及任务本身…再次在任务和线程之间的上下文切换…

移动到一个多CPU,内核将被设置为可扩展的,调度程序会做什么,将一个task加载到一个CPU,另一个加载到另一个CPU(双核),并跳转到指令的地方指针指向…现在内核真的在两个CPU上同时运行这两个任务。 扩展到4路,同样的东西,加载到每个CPU上的附加任务,再次扩展,以n路…你得到的漂移。

正如你所看到的那样,线程不会被视为可扩展的概念,因为内核在跟踪cpu运行什么方面非常坦率地工作,而且最重要的是运行哪些线程,从根本上来说解释了为什么我认为线程不完全可扩展…线程消耗了大量的资源…

如果您真的想看看发生了什么,请查看Linux的源代码,特别是在调度程序中。 没有挂,忘记了2.6.x内核版本,看史前版本0.99,调度程序会更容易理解,更容易阅读,当然,它有点旧,但值得一看,这将有助于你理解为什么,也希望我的答案,为什么线程不可扩展……并显示玩具操作系统如何使用基于进程的时间划分。 我努力不去涉及现代CPU的技术方面,可以做更多的事情,正如我所描述的…

希望这可以帮助。

一位教授曾经在课堂上告诉我们,Windows,Linux,OS X和UNIX在线程上而不是在进程上扩展,所以即使是在单个处理器上,线程也可能会对你的应用程序有利,因为你的应用程序在CPU上获得更多的时间。

不必要。 如果你的应用程序是唯一的CPU密集型的东西运行,更多的线程不会神奇地使更多的CPU时间可用 – 所有这些将导致上下文切换浪费更多的CPU时间。

这个我想,“哇,线程吮吸”。 但是,在四台处理器的大学服务器上重复测试接近四倍的速度。

这是因为有四个线程,它可以使用全部四个处理器。

我不确定你在问什么,但这里有一个答案,可能有帮助。

在Linux下,进程和线程本质上是完全一样的。 调度器理解所谓的“任务”,它并不关心它们是否共享地址空间。 共享或不共享的东西真的取决于他们是如何创建的。

是否使用线程或进程是一个关键的设计决策,不应掉以轻心,但调度程序的性能可能不是一个因素(当然,像IPC的要求会大大改变设计)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值