cpu 指定cpu执行 java_在指定cpu的核心上执行线程 - Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere - C++...

本文介绍了如何在Linux系统中使用C语言通过`sched_setaffinity`函数来指定CPU核心执行Java线程,通过示例代码展示了如何将进程绑定到特定CPU,以优化性能。同时,对比了Windows环境下使用`SetThreadAffinityMask`进行类似操作的方法。
摘要由CSDN通过智能技术生成

cpu.c

[CODE]

#include

#include

#include

#include

#include

#define __USE_GNU

#include

#include

#include

int main(int argc, char* argv[])

{

int num = sysconf(_SC_NPROCESSORS_CONF);

int created_thread = 0;

int myid;

int i;

int j = 0;

cpu_set_t mask;

cpu_set_t get;

if (argc != 2)

{

printf("usage : ./cpu num\n");

exit(1);

}

myid = atoi(argv[1]);

printf("system has %i processor(s). \n", num);

CPU_ZERO(&mask);

CPU_SET(myid, &mask);

if (sched_setaffinity(0, sizeof(mask), &mask) == -1)

{

printf("warning: could not set CPU affinity, continuing...\n");

}

while (1)

{

CPU_ZERO(&get);

if (sched_getaffinity(0, sizeof(get), &get) == -1)

{

printf("warning: cound not get cpu affinity, continuing...\n");

}

for (i = 0; i 

{

if (CPU_ISSET(i, &get))

{

printf("this process %d is running processor : %d\n",getpid(), i);

}

}

}

return 0;

}

[/CODE]

下面是在两个终端分别执行了./cpu 0  ./cpu 2 后得到的结果. 效果比较明显.

Cpu0  :  5.3%us,  5.3%sy,  0.0%ni, 87.4%id,  0.0%wa,  0.0%hi,  2.0%si,  0.0%st

Cpu1  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu2  :  5.0%us, 12.2%sy,  0.0%ni, 82.8%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu3  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu4  :  0.0%us,  0.0%sy,  0.0%ni, 99.7%id,  0.3%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu5  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu6  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

Cpu7  :  0.0%us,  0.0%sy,  0.0%ni,100.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st#ifdef __USE_GNU

/* Access macros for `cpu_set'.  */

#define CPU_SETSIZE __CPU_SETSIZE

#define CPU_SET(cpu, cpusetp)   __CPU_SET (cpu, cpusetp)

#define CPU_CLR(cpu, cpusetp)   __CPU_CLR (cpu, cpusetp)

#define CPU_ISSET(cpu, cpusetp) __CPU_ISSET (cpu, cpusetp)

#define CPU_ZERO(cpusetp)       __CPU_ZERO (cpusetp)

/* Set the CPU affinity for a task */

extern int sched_setaffinity (__pid_t __pid, size_t __cpusetsize,

__const cpu_set_t *__cpuset) __THROW;

/* Get the CPU affinity for a task */

extern int sched_getaffinity (__pid_t __pid, size_t __cpusetsize,

cpu_set_t *__cpuset) __THROW;

#endif#define __USE_GNU是为了使用CPU_SET()等宏. 具体在/usr/include/sched.h中有如下的定义.CPU Affinity (CPU亲合力)

CPU亲合力就是指在Linux系统中能够将一个或多个进程绑定到一个或多个处理器上运行.

一个进程的CPU亲合力掩码决定了该进程将在哪个或哪几个CPU上运行.在一个多处理器系统中,设置CPU亲合力的掩码可能会获得更好的性能.

一个CPU的亲合力掩码用一个cpu_set_t结构体来表示一个CPU集合,下面的几个宏分别对这个掩码集进行操作:

CPU_ZERO() 清空一个集合

CPU_SET()与CPU_CLR()分别对将一个给定的CPU号加到一个集合或者从一个集合中去掉.

CPU_ISSET()检查一个CPU号是否在这个集合中.

其实这几个的用法与select()函数那几个调用差不多.

下面两个函数就是最主要的了:

sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

该函数设置进程为pid的这个进程,让它运行在mask所设定的CPU上.如果pid的值为0,则表示指定的是当前进程,使当前进程运行在mask所设定的那些CPU上.第二个参数cpusetsize是

mask所指定的数的长度.通常设定为sizeof(cpu_set_t).如果当前pid所指定的CPU此时没有运行在mask所指定的任意一个CPU上,则该指定的进程会从其它CPU上迁移到mask的指定的

一个CPU上运行.

sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)

该函数获得pid所指示的进程的CPU位掩码,并将该掩码返回到mask所指向的结构中.即获得指定pid当前可以运行在哪些CPU上.同样,如果pid的值为0.也表示的是当前进程.

这几个宏与函数的具体用法前面已经有讲解.

关于cpu_set_t的定义

[CODE]

# define __CPU_SETSIZE  1024

# define __NCPUBITS     (8 * sizeof (__cpu_mask))

typedef unsigned long int __cpu_mask;

# define __CPUELT(cpu)  ((cpu) / __NCPUBITS)

# define __CPUMASK(cpu) ((__cpu_mask) 1 <

typedef struct

{

__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];

} cpu_set_t;

# define __CPU_ZERO(cpusetp) \

do {                                                                        \

unsigned int __i;                                                         \

cpu_set_t *__arr = (cpusetp);                                             \

for (__i = 0; __i 

__arr->__bits[__i] = 0;                                                 \

} while (0)

# define __CPU_SET(cpu, cpusetp) \

((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))

# define __CPU_CLR(cpu, cpusetp) \

((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))

# define __CPU_ISSET(cpu, cpusetp) \

(((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)

[/CODE]

在我的机器上sizeof(cpu_set_t)的大小为128,即一共有1024位.第一位代表一个CPU号.某一位为1则表示某进程可以运行在该位所代表的cpu上.例如

CPU_SET(1, &mask);

则mask所对应的第2位被设置为1.

此时如果printf("%d\n", mask.__bits[0]);就打印出2.表示第2位被置为1了.

具体我是参考man sched_setaffinity文档中的函数的.

然后再参考了一下IBM的 developerWorks上的一个讲解.

http://www.ibm.com/developerworks/cn/linux/l-affinity.html

-----------------------------------------------------------------

windows  首先用API函数创建一个线程,

HANDLE CreateThread(

LPSECURITY_ATTRIBUTESlpThreadAttributes, // SD

SIZE_TdwStackSize,// initial stack size

LPTHREAD_START_ROUTINElpStartAddress,// thread function

LPVOIDlpParameter,// thread argument

DWORDdwCreationFlags,// creation option

LPDWORDlpThreadId     // thread identifier

);

通过调用SetThreadAffinityMask,就能为各个线程设置亲缘性屏蔽:

DWORD_PTR SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffinityMask );

该函数中的hThread参数用于指明要限制哪个线程,

dwThreadAffinityMask用于指明该线程能够在哪个CPU上运行。

dwThreadAffinityMask必须是进程的亲缘性屏蔽的相应子集。

返回值是线程的前一个亲缘性屏蔽。因此,若要将3个线程限制到CPU1、2和3上去运行,可以这样操作:

//Thread 0 can only run on CPU 0.

SetThreadAffinityMask(hThread0, 0x00000001);

//Threads 1, 2, 3 run on CPUs 1.

SetThreadAffinityMask(hThread1, 0x0000000E);

posted on 2009-12-29 16:57 Khan 阅读(4604) 评论(0)  编辑 收藏 引用 所属分类: GCC/G++ 、跨平台开发

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值