如何设置指定进程如何获得CPU的CPU亲和性

管理处理器的亲和性(affinity)
简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现 硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。
什么是 Linux 内核硬亲和性(affinity)?
在 Linux 内核中,所有的进程都有一个相关的数据结构,称为 task_struct。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是 cpus_allowed 位掩码。这个位掩码由 n 位组成,与系统中的 n 个逻辑处理器一一对应。
具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。
如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。
Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:
sched_set_affinity() (用来修改位掩码)sched_get_affinity() (用来查看当前的位掩码)
注意,cpu_affinity 会被传递给子线程,因此应该适当地调用 sched_set_affinity。
为什么应该使用硬亲和性(affinity)?
通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU 之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。
一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。
原因 1. 有大量计算要做
基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。
原因 2. 您在测试复杂的应用程序
测试复杂软件是我们对内核的亲和性(affinity)技术感兴趣的另外一个原因。考虑一个需要进行线性可伸缩性测试的应用程序。有些产品声明可以在 使用更多硬件 时执行得更好。
我们不用购买多台机器(为每种处理器配置都购买一台机器),而是可以:
购买一台多处理器的机器不断增加分配的处理器测量每秒的事务数评估结果的可伸缩性
如果应用程序随着 CPU 的增加可以线性地伸缩,那么每秒事务数和 CPU 个数之间应该会是线性的关系(例如斜线图 —— 请参阅下一节的内容)。这样建模可以确定应用程序是否可以有效地使用底层硬件。
Amdahl 法则说明这种加速比在现实中可能并不会发生,但是可以非常接近于该值。对于通常情况来说,我们可以推论出每个程序都有一些串行的组件。随着问题集不断变大,串行组件最终会在优化解决方案时间方面达到一个上限。
Amdahl 法则在希望保持高 CPU 缓存命中率时尤其重要。如果一个给定的进程迁移到其他地方去了,那么它就失去了利用 CPU 缓存的优势。实际上,如果正在使用的 CPU 需要为自己缓存一些特殊的数据,那么所有其他 CPU 都会使这些数据在自己的缓存中失效。
因此,如果有多个线程都需要相同的数据,那么将这些线程绑定到一个特定的 CPU 上是非常有意义的,这样就确保它们可以访问相同的缓存数据(或者至少可以提高缓存的命中率)。否则,这些线程可能会在不同的 CPU 上执行,这样会频繁地使其他缓存项失效。
原因 3. 您正在运行时间敏感的、决定性的进程
我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。
下面的样例应用程序显示了这是如何工作的。
如何利用硬亲和性(affinity)
现在让我们来设计一个程序,它可以让 Linux 系统非常繁忙。可以使用前面介绍的系统调用和另外一些用来说明系统中有多少处理器的 API 来构建这个应用程序。实际上,我们的目标是编写这样一个程序:它可以让系统中的每个处理器都繁忙几秒钟。可以从后面的“下载”一节中 。
清单 1. 让处理器繁忙/* This method will create threads, then bind each to its own cpu. */
bool do_cpu_stress(int numthreads)
int ret = TRUE;
int created_thread = 0;
/* We need a thread for each cpu we have... */
while ( created_thread & numthreads - 1 )
int mypid = fork();
if (mypid == 0) /* Child process */
printf("\tCreating Child Thread: #%i\n", created_thread);
else /* Only parent executes this */
/* Continue looping until we spawned enough threads! */ ;
created_thread++;
/* NOTE: All threads execute code from here down! */
正如您可以看到的一样,这段代码只是通过 fork 调用简单地创建一组线程。每个线程都执行这个方法中后面的代码。现在我们让每个线程都将亲和性(affinity)设置为自己的 CPU。
清单 2. 为每个线程设置 CPU 亲和性(affinity)
/* CPU_ZERO initializes all the bits in the mask to zero. */
CPU_ZERO( &mask );
/* CPU_SET sets only the bit corresponding to cpu. */
CPU_SET( created_thread, &mask );
/* sched_setaffinity returns 0 in success */
if( sched_setaffinity( 0, sizeof(mask), &mask ) == -1 )
printf("WARNING: Could not set CPU Affinity, continuing...\n");
如果程序可以执行到这儿,那么我们的线程就已经设置了自己的亲和性(affinity)。调用 sched_setaffinity 会设置由 pid 所引用的进程的 CPU 亲和性(affinity)掩码。如果 pid 为 0,那么就使用当前进程。
亲和性(affinity)掩码是使用在 mask 中存储的位掩码来表示的。最低位对应于系统中的第一个逻辑处理器,而最高位则对应于系统中最后一个逻辑处理器。
每个设置的位都对应一个可以合法调度的 CPU,而未设置的位则对应一个不可调度的 CPU。换而言之,进程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了。这些线程的亲和性(affinity)都会传递给从它们派生的子进程中。
注意不应该直接修改位掩码。应该使用下面的宏。虽然在我们的例子中并没有全部使用这些宏,但是在本文中还是详细列出了这些宏,您在自己的程序中可能需要这些宏。
清单 3. 间接修改位掩码的宏void CPU_ZERO (cpu_set_t *set)
这个宏对 CPU 集 set 进行初始化,将其设置为空集。
void CPU_SET (int cpu, cpu_set_t *set)
这个宏将 cpu 加入 CPU 集 set 中。
void CPU_CLR (int cpu, cpu_set_t *set)
这个宏将 cpu 从 CPU 集 set 中删除。
int CPU_ISSET (int cpu, const cpu_set_t *set)
如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。
对于本文来说,样例代码会继续让每个线程都执行某些计算量较大的操作。
清单 4. 每个线程都执行一个计算敏感的操作
/* Now we have a single thread bound to each cpu on the system */
int computation_res = do_cpu_expensive_op(41);
sched_getaffinity(0, sizeof(mycpuid), &mycpuid);
if ( check_cpu_expensive_op(computation_res) )
printf("SUCCESS: Thread completed, and PASSED integrity check!\n",
ret = TRUE;
printf("FAILURE: Thread failed integrity check!\n",
ret = FALSE;
现在您已经了解了在 Linux 2.6 版本的内核中设置 CPU 亲和性(affinity)的基本知识。接下来,我们使用一个 main 程序来封装这些方法,它使用一个用户指定的参数来说明要让多少个 CPU 繁忙。我们可以使用另外一个方法来确定系统中有多少个处理器:
int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF);
这个方法让程序能够自己确定要让多少个处理器保持繁忙,例如缺省让所有的处理器都处于繁忙状态,并允许用户指定系统中实际处理器范围的一个子集。
运行样例程序
当运行前面介绍的
时,可以使用很多工具来查看 CPU 是否是繁忙的。如果只是简单地进行测试,可以使用 Linux 命令 top。在运行 top 命令时按下 “1” 键,可以看到每个 CPU 执行进程所占用的百分比。
这个样例程序虽然非常简单,但是它却展示了使用 Linux 内核中实现的硬亲和性(affinity)的基本知识。(任何使用这段代码的应用程序都无疑会做一些更有意义的事情。)了解了 CPU 亲和性(affinity)内核 API 的基本知识,您就可以从复杂的应用程序中榨取出最后一点儿性能了。
下载资源 (thrasher.zip | 3 KB)相关主题您可以参阅本文在 developerWorks 全球站点上的 。
“” (developerWorks,2003 年 1 月)给出了对超线程在 Linux SMP 内核中的影响的研究结果。
“” (developerWorks,2005 年 5 月)展示了使用 CPU 亲和性(affinity)来确定性能问题的 Linux 模块工具。
“” (CCR2,2004 年 9 月)解释了什么可以改进调度器(包括 CPU 亲和性(affinity))。
中可以找到更多为 Linux 开发人员提供的参考资料。
在您的下一个开发项目中采用 ,这可以从 developerWorks 上直接下载。
添加或订阅评论,请先或。
有新评论时提醒我
static.content.url=http://www.ibm.com/developerworks/js/artrating/SITE_ID=10Zone=LinuxArticleID=99000ArticleTitle=管理处理器的亲和性(affinity)publish-date=查看: 3960|回复: 4
设置进程(线程)在指定的CPU上运行,建议官方添加!
阅读权限90
签到天数:1 天结帖率: (9/9)
本帖最后由 萧阳天 于
20:13 编辑
今天写的软件在别人那里一运行就出错。还以为多线程代码写错了。找了一个晚上问题,才发现他的电脑是单核的。
实现方法进程与指定cpu绑定:
SetProcessAffinityMask(GetCurrentProcess(),dwMask);
线程与指定cpu绑定:SetThreadAffinityMask(GetCurrentThread(),dwMask);
dwMask为CPU序号的或运算值:1(0001)代表只运行在CPU1,2(0010)代表只运行在CPU2,3(0011)代表可以运行在CPU1和CPU2,以此类推。
设置之前最好判断一下系统有几个CPU:
SYSTEM_INFOSystemIGetSystemInfo(&SystemInfo);
CPU个数:SystemInfo.dwNumberOfProcessors
当前启用的CPU序号:SystemInfo.dwActiveProcessorMask,Mask representing the set of processors configured into the system. Bit 0 is processor 0;
bit 31 is processor 31.
CPU亲缘性介绍按照默认设置,当系统将线程分配给处理器时,Windows使用软亲缘性来进行操作。这意味着如果所有其他因素相同的话,它将设法在它上次运行的那个处理器上运行线程。让线程留在单个处理器上,有助于重复使用仍然在处理器的内存高速缓存中的数据。有一种新的计算机结构,称为NUMA(非统一内存访问),在该结构中,计算机包含若干块插件板,每个插 件板上有4个CPU和它自己的内存区。当CPU访问的内存是它自己的插件板上的内存时,NUMA系统运行的性能最好。如果CPU需要访问位于另一个插件板上的内 存时,就会产生巨大的性能降低。在这样的环境中,就需要限制来自一个进程中的线程在共享同一个插件版的CPU上运行。为了适应这种计算机结构的需要,Windows允许你设置进程和线程的亲缘性。换句话说,你可以控制哪个CPU能够运行某些线程。这称为硬亲缘性。请注意,子进程可以继承进程的亲缘性。注意:(1)无论计算机中实际拥有多少个CPU,Windows98及以前系统只使用一个CPU,上述API不被支持。(2)在大多数环境中,改变线程的亲缘性就会影响调度程序有效地在 各个CPU之间移植线程的能力,而这种能力可以最有效地使用CPU时间。应用场景举例:将UI线程限制在一个CPU,将其他实时性要求较高的线程限制在另一个CPU。这样,当UI需要占用大量CPU时间时,就不会拖累其他实时性要求较高的线程的执行。同样可以将UI线程与一些优先级不高但耗时的异步运算线程设置在不同CPU上,避免UI给人卡顿的感觉。
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
揭阳精易科技有限公司申明:我公司所有的培训课程版权归精易所有,任何人以任何方式翻录、盗版、破解本站培训课程,我们必将通过法律途径解决!
公司简介:揭阳市揭东区精易科技有限公司致力于易语言教学培训/易语言学习交流社区的建设与软件开发,多年来为中小企业编写过许许多多各式软件,并把多年积累的开发经验逐步录制成视频课程供学员学习,让学员全面系统化学习易语言编程,少走弯路,减少对相关技术的研究与摸索时间,从而加快了学习进度!
防范网络诈骗,远离网络犯罪
违法和不良信息举报电话,QQ: ,邮箱:@b.qq.com
Powered by
X3.2 揭阳市揭东区精易科技有限公司
粤公网安备 25今天看到运维的同事在配置nginx的CPU亲和性时候,运维同事说他在所有的机器上都是按照8核的方式来配置worker进程的CPU亲和性的。
但我觉得就是有点不太对劲,就查了一下nginx的处理worker_cpu_affinity的源代码,发现nginx并不会在发现配置错误的时候拒绝启动worker进程,而是仅仅打印一条错误日志&sched_setaffinity() failed&。
如果设置亲和性失败则按照SMP负载策略进行处理,linux的SMP负载均衡是基于进程数的,每个cpu都有一个可执行进程队列,只有当其中一个cpu的可执行队列里进程数比其他cpu队列进程数多25%时,才会将进程移动到另外空闲cpu上,也就是说cpu0上的进程数应该是比其他cpu上多,但是会在25%以内,呈现的是一种梯形分布。
如果都使用8核的方式,那么配置在4核的机器上,就会有约一半进程是按照SMP方式分配CPU的;配置在16核机器上,就会有约一半的CPU核心空闲。
我是喜欢打破砂锅问到底的,那么就顺道写了一些测试程序来研究一下Linux下的CPU亲和性在不同设置的情况下是什么状况。
测试前提:
系统是8个CPU逻辑核心(cpu0-cpu7)。
可以通过cat /proc/cpuinfo查看. 也可以使用 int num_procs = sysconf(_SC_NPROCESSORS_CONF); 获取CPU逻辑核心的数量
#define _GNU_SOURCE
#include &sched.h&
#include &unistd.h&
运行之后,
ps -eo pid,args,psr | grep cpu_affinity_test 查看该进程所占用的cpu,
可以看到这个程序一定是运行在cpu7上。
如果把 CPU_SET(7, &mask);
修改为 CPU_SET(8, &mask);
再编译运行,则CPU亲和性设置会失败,系统会随机给该进程分配一个cpu,但也会固定下来。
如果修改为 CPU_SET(6, &mask); CPU_SET(7, &mask);
再编译运行,理论上会绑定两个CPU,由于这个进程再每次打印之前会休息1秒,所以基本都是在占用cpu6, 如果再修改一下程序,把休息时间修改为1毫秒,则会发现该进程会交替使用cpu6和cpu7。
如果修改为 CPU_SET(6, &mask); CPU_SET(8, &mask);
再编译运行,则cpu6被绑定成功,而cpu8是不存在的,所以该进程就只会在cpu6上运行。
备注: linux的SMP负载均衡是基于进程数的,每个cpu都有一个可执行进程队列,只有当其中一个cpu的可执行队列里进程数比其他cpu队列进程数多25%时,才会将进程移动到另外空闲cpu上,也就是说cpu0上的进程数应该是比其他cpu上多,但是会在25%以内。它也自带负载均衡策略,可以在运行时将某些进程从某一个cpu核心的进程队列移到另外一个cpu核心的进程队列。
https://my.oschina.net/xuhh/blog/755825
Views(...) Comments()如何设置指定进程的CPU亲和性_百度知道
如何设置指定进程的CPU亲和性
我有更好的答案
实现方法进程与指定cpu绑定:SetProcessAffinityMask(GetCurrentProcess(),dwMask);线程与指定cpu绑定:SetThreadAffinityMask(GetCurrentThread(),dwMask);dwMask为CPU序号的或运算值:1(0001)代表只运行在CPU1,2(0010)代表只运行在CPU2,3(0011)代表可以运行在CPU1和CPU2,以此类推。英特尔最新推出了第六代酷睿产品,采用全新一代的架构,性能提示、功能降低、续航更加长久、无论办公学习、畅玩游戏或者观看超高清音箱播放,均得心应手,您也可以试试。
采纳率:90%
来自团队:
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。博客访问: 822093
博文数量: 327
博客积分: 10135
博客等级: 上将
技术积分: 2500
注册时间:
原文地址: 作者:
进程和线程的亲缘性(affinity)是指可以将进程或者是线程强制限制在可用的CPU子集上运行的特性,它一定程度上把进程/线程在多处理器系统上的调度策略暴露给系统程序员。
CPU的数量和表示在有n个CPU的Linux上,CPU是用0...n-1来进行一一标识的。CPU的数量可以通过proc文件系统下的CPU相关文件得到,如cpuinfo和stat:$ cat /proc/stat | grep "^cpu[0-9]\+" | wc -l8$ cat /proc/cpuinfo | grep "^processor" | wc -l8在系统编程中,可以直接调用库调用sysconf获得:sysconf(_SC_NPROCESSORS_ONLN);进程的亲缘性Linux操作系统在2.5.8引入了调度亲缘性相关的系统调用:intsched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);intsched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);其中sched_setaffinity是设定进程号为pid的进程调度亲缘性为mask,也就是说它只能在mask中指定的CPU之间进行调度执行;sched_getaffinity当然就是得到进程号为pid的进程调度亲缘性了。如果pid为0,则操纵当前进程。第二个参数指定mask所指空间的大小,通常为sizeof(cpu_set_t)。第三个参数mask的类型为cpu_set_t,即CPU集合,GNU的c库(需要在include头文件之前定义__USE_GNU)还提供了操作它们的宏:voidCPU_CLR(int cpu, cpu_set_t *set);intCPU_ISSET(int cpu, cpu_set_t *set);voidCPU_SET(int cpu, cpu_set_t *set);voidCPU_ZERO(cpu_set_t *set);
如果我们所关心的只是CPU#0和CPU#1,想确保我们的进程只会运作在CPU#0之上,而不会运作在CPU#1之上。下面程序代码可以完成此事:
cpu_set_t&set;&&
int&ret,&i;&&
CPU_ZERO(&set);&&
CPU_SET(0,&&set);&&
CPU_CLR(1,&&set);&&
ret&=&sched_setaffinity(0,&sizeof(cpu_set_t),&&set);&&
if(&ret&==&-1)&&
&&&&&&&&perror("sched_se");&&
for(&i=0;&i&<&3;&i++)&&
&&&&&&&&int&&&
&&&&&&&&cpu&=&CPU_ISSET(i,&&set);&&
&&&&&&&&printf("cpu&=&%i&is&%s/n",&i,&&
&&&&&&&&&&&&&&&&cpu?&"set"&:&"unset");&&
Linux只提供了面向线程的调度亲缘性一种接口,这也是上面只提调度亲缘性而不直言进程亲缘性的原因。当前Linux系统下广泛采用的线程库NPTL(Native Posix Thread Library)是基于线程组来实现的,同一个线程组中的线程对应于一组共享存储空间的轻量级进程,它们各自作为单独调度单位被内核的调度器在系统范围内调度,这种模型也就是我们通常所说的1-1线程模型。正因如此,目前线程的调度范围(可以用函数pthread_attr_getscope和pthread_attr_setscope获取和设置)只能是系统级而不能是进程级。
c库的GNU扩展所提供的有关线程亲缘性的API如下:int pthread_attr_setaffinity_np (pthread_attr_t *__attr, size_t __cpusetsize, __const cpu_set_t *__cpuset);intpthread_attr_getaffinity_np (__const pthread_attr_t *__attr, size_t __cpusetsize, cpu_set_t *__cpuset);int pthread_setaffinity_np (pthread_t __th, size_t __cpusetsize, __const cpu_set_t *__cpuset);intpthread_getaffinity_np (pthread_t __th, size_t __cpusetsize, cpu_set_t *__cpuset);亲缘性的继承调度亲缘性是被fork出来的子进程所继承的,即使子进程通过exec系列函数更换了执行镜像。因为Linux操作系统下进程和线程的创建都是通过系统调用clone来实现的,所以实际上调度亲缘性也是被用pthread_create创建的线程所继承的。这意味着,如果主线程在创建其它线程之前设定亲缘性,那么它所设定的亲缘性将被继承,因为这时所有线程的亲缘性相同(假设之后没有任何线程私自设置亲缘性),我们就可以认为前面设置的是进程亲缘性,而不管它所调用的函数是sched_setaffinity还是pthread_setaffnity_np。
下面创建两个并发线程分别绑定在CPU0和CPU1上。
#define _GNU_SOURCE
#include #include
#include #include #include #include #include #include #include #include
int x1;int x2;
double waste_time(long n){&&&&&&& double res = 0;&&&&&&& long i = 0;&&&&&&& while (i <n * 500000) {&&&&&&&&&&&&&&& i++;&&&&&&&&&&&&&&& res += sqrt(i);&&&&&&& }&&&&&&&}
void* proc1(void*arg){
&&& cpu_set_&&& CPU_ZERO(&mask);&&& CPU_SET(0,&mask);&&& int ret = 0;&&& &&&& ret = pthread_setaffinity_np(pthread_self(),sizeof(mask),(const cpu_set_t*)&mask );&&&& if(ret < 0)&&& {&&&&&&& printf("pthread_setaffinity_np err \n");&&&&&&&&&& }&&& while(1)&&& {&&&&&&& if(x1 > )&&&&&&& {&&&&&&&&&&&&&&&&&& }&&&&&&& x1++;&&& }&&& waste_time(1);&&& ret =pthread_getaffinity_np(pthread_self(),sizeof(mask),(const cpu_set_t*)&mask );&&& if(ret < 0)&&& {&&&&&&& printf("pthread_getaffinity_np err \n");&&&&&&&&&& }&&&&&& for( j = 0;j < CPU_SETSIZE;j++)&&& {&&&&&&& if(CPU_ISSET(j,&mask))&&&&&&&&&&& printf(" thread[%d] bind cpu[%d]\n",pthread_self(),j);&&& }
void* proc2(void* arg){
&&& cpu_set_&&& CPU_ZERO(&mask);&&& CPU_SET(2,&mask);&&& int ret = 0;&&& &&& ret =pthread_setaffinity_np(pthread_self(),sizeof(mask),(const cpu_set_t*)&mask );&&& if(ret < 0)&&& {&&&&&&& printf("pthread_setaffinity_np err \n");&&&&&&&&&& }
&&& while(1)&&& {&&&&&&& if(x2 > )&&&&&&& {&&&&&&&&&&&&&&&&&& }&&&&&&& x2++;&&& }&&& waste_time(1);&&& ret =pthread_getaffinity_np(pthread_self(),sizeof(mask),(const cpu_set_t*)&mask );&&& if(ret < 0)&&& {&&&&&&& printf("pthread_getaffinity_np err \n");&&&&&&&&&& }&&&&&& for( j = 0;j < CPU_SETSIZE;j++)&&& {&&&&&&& if(CPU_ISSET(j,&mask))&&&&&&&&&&& printf(" thread[%d] bind cpu[%d]\n",pthread_self(),j);&&& }}
void main(){&&& &&&&&& pthread_t t1,t2;&&& struct timeval time1,time2;&&& &&& ret = gettimeofday(&time1,NULL);&&& ret = pthread_create(&t1,NULL,proc1,NULL);&&& &&& ret = pthread_create(&t2,NULL,proc2,NULL);&&& pthread_join(t1,NULL);&&& pthread_join(t2,NULL);&&& ret = gettimeofday(&time2,NULL);&&& printf("time spend:[%d]s [%d]ms \n",time2.tv_sec - time1.tv_sec,(time2.tv_usec - time1.tv_usec)/1000);
阅读(890) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
请登录后评论。

我要回帖

更多关于 进程如何获得CPU 的文章

 

随机推荐