Linux编程之《进程/线程绑定CPU》
Intro
-----
通常我们在编写服务器代码时,可以通过将当前进程绑定到固定的CPU核心或者线程绑定到固定的CPU核心来提高系统调度程序的效率来提高程序执行的效率,下面将完整代码贴上。
/************************************************
* 该例程讲解了进程、线程绑定到固定的cpu核心上运行
* 来提高程序运行效率
************************************************/
#include <unistd.h>
#ifndef __USE_GNU
#define __USE_GNU // 为了使用SET_SET()等宏定义,但unistd.h里面好像已经定义了
#endif
#include <sched.h>
#include <pthread.h>
#include <stdio.h>
#include <vector> unsigned int systemCPUNum()
{
// _SC_NPROCESSORS_CONF的值为CPU个数,基于0开始编号
return sysconf(_SC_NPROCESSORS_CONF);
} bool currentProcessAffinity(std::vector<unsigned int>& runningCPUVector)
{
cpu_set_t cpuSet; // 清空一个CPU集合
CPU_ZERO(&cpuSet); // 得到指定进程ID绑定到哪个CPU
int ret = sched_getaffinity(, // 0代表当前进程
sizeof(cpuSet),
&cpuSet);
if (ret < )
{
return false;
} unsigned int cpuNum = systemCPUNum();
runningCPUVector.clear();
for (unsigned int i = ; i < cpuNum; ++i)
{
// 检查一个CPU号是否在一个集合中
if (CPU_ISSET(i, &cpuSet))
{
runningCPUVector.push_back(i);
}
} return true;
} bool setCurrentProcessAffinity(const std::vector<unsigned int>& needBindCPUVector)
{
cpu_set_t cpuSet; // 清空一个CPU集合
CPU_ZERO(&cpuSet); for (auto& iter : needBindCPUVector)
{
CPU_SET(iter, &cpuSet);
} // 将指定进程ID绑定到CPU
int ret = sched_setaffinity(, // 0代表当前进程
sizeof(cpuSet),
&cpuSet);
if (ret < )
{
return false;
} return true;
} bool currentThreadAffinity(std::vector<unsigned int>& runningCPUVector)
{
cpu_set_t cpuSet; // 清空一个CPU集合
CPU_ZERO(&cpuSet); // 得到指定线程ID绑定到哪个CPU
int ret = pthread_getaffinity_np(pthread_self(),
sizeof(cpuSet),
&cpuSet);
if (ret < )
{
return false;
} unsigned int cpuNum = systemCPUNum();
runningCPUVector.clear();
for (unsigned int i = ; i < cpuNum; ++i)
{
// 检查一个CPU号是否在一个集合中
if (CPU_ISSET(i, &cpuSet))
{
runningCPUVector.push_back(i);
}
} return true;
} bool setCurrentThreadAffinity(const std::vector<unsigned int>& needBindCPUVector)
{
cpu_set_t cpuSet; // 清空一个CPU集合
CPU_ZERO(&cpuSet); for (auto& iter : needBindCPUVector)
{
CPU_SET(iter, &cpuSet);
} // 将指定线程ID绑定到CPU
int ret = pthread_setaffinity_np(pthread_self(),
sizeof(cpuSet),
&cpuSet);
if (ret < )
{
return false;
} return true;
} int main()
{
printf("*****Process bind CPU sample*****\n");
unsigned int cpuNum = systemCPUNum();
printf("Current system has %u CPU(s)\n", cpuNum); std::vector<unsigned int> runningCPUVector;
if (!currentProcessAffinity(runningCPUVector))
{
printf("Get current process was bound witch CPU failed\n");
return ;
} for (auto& iter : runningCPUVector)
{
printf("Current process is running at %u CPU\n", iter);
} std::vector<unsigned int> needBindCPUVector {, };
if (!setCurrentProcessAffinity(needBindCPUVector))
{
printf("Current process bind CPU failed\n");
return ;
} printf("Current process bind CPU success\n"); runningCPUVector.clear();
if (!currentProcessAffinity(runningCPUVector))
{
printf("Get current process was bound witch CPU failed\n");
return ;
} for (auto& iter : runningCPUVector)
{
printf("Current process is running at %u CPU\n", iter);
} printf("\n*****Thread bind CPU sample*****\n");
runningCPUVector.clear();
if (!currentThreadAffinity(runningCPUVector))
{
printf("Get current thread was bound witch CPU failed\n");
return ;
} for (auto& iter : runningCPUVector)
{
printf("Thread %lu is running at %u CPU\n", pthread_self(), iter);
} needBindCPUVector.clear();
needBindCPUVector.push_back();
if (!setCurrentThreadAffinity(needBindCPUVector))
{
printf("Current thread bind CPU failed\n");
return ;
} printf("Thread %lu bind CPU success\n", pthread_self()); runningCPUVector.clear();
if (!currentThreadAffinity(runningCPUVector))
{
printf("Get current thread was bound witch CPU failed\n");
return ;
} for (auto& iter : runningCPUVector)
{
printf("Thread %lu is running at %u CPU\n", pthread_self(), iter);
} return ;
}
程序执行的输出结果:
*****Process bind CPU sample*****
Current system has 4 CPU(s)
Current process is running at 0 CPU
Current process is running at 1 CPU
Current process is running at 2 CPU
Current process is running at 3 CPU
Current process bind CPU success
Current process is running at 0 CPU
Current process is running at 2 CPU
*****Thread bind CPU sample*****
Thread 139871129114432 is running at 0 CPU
Thread 139871129114432 is running at 2 CPU
Thread 139871129114432 bind CPU success
Thread 139871129114432 is running at 1 CPU
该例子的github地址:https://github.com/chxuan/samples/blob/master/BindCPU/BindCPU.cpp
Linux编程之《进程/线程绑定CPU》的更多相关文章
- Linux编程之《看门狗进程》
Intro 当我们编写服务器代码时,为了让自己的服务器在意外崩溃时能够及时的重启,软件看门狗就显示出它的作用了,该看门狗进程是通过fork一个子进程(业务进程),父进程一旦捕获到了子进程的结束信号就重 ...
- Linux编程之《守护进程》
Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常 ...
- Linux编程 7 (实时监测进程 top, 结束进程kill,killall)
一. 实时监测进程 top 在一篇里讲到ps命令在收集进程信息时非常有用,但它只能显示某个特定时间点的信息.想要观察那些频繁换进换出的内存进程趋势,用top命令是合适的.使用top命令如下图所示: 在 ...
- 10.3、android输入系统_必备Linux编程知识_任意进程双向通信(scoketpair+binder)
3. 任意进程间通信(socketpair_binder) 进程每执行一次open打开文件,都会在内核中有一个file结构体表示它: 对每一个进程在内核中都会有一个task_struct表示进程,这个 ...
- Linux 下如何使用看门狗
Linux内核有集成WD的选项.将其使能后,系统里就会有watchdog的设备驱动:/dev/watchdog.这样,在应用程序里只需打开这个设备使用即可:#include <fcntl.h ...
- Linux 软件看门狗 watchdog 喂狗
Linux 自带了一个 watchdog 的实现,用于监视系统的运行,包括一个内核 watchdog module 和一个用户空间的 watchdog程序.内核 watchdog 模块通过 /dev/ ...
- 【目录】linux 编程
随笔分类 - linux 编程 Linux编程 24 shell编程(结构化 if [ condition ] 数值比较,字符串比较) 摘要: 一.概述 接着上篇讲的结构化命令,最后讲到了test命令 ...
- linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】
本文转载自:http://blog.chinaunix.net/uid-25014876-id-112879.html linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxx ...
- linux内核中断之看门狗
一:内核中断 linux内核中的看门狗中断跟之前的裸板的中断差不多,在编写驱动之前,需要线把内核自带的watch dog模块裁剪掉,要不然会出现错误:在Device Drivers /Watchdog ...
- Linux C语言编程学习笔记 (1)进程控制入门
想进行Linux系统开发已经很久了,一直没有付诸实践.今日终于开始学习Linux下的C语言编程,研究一天,终于大概弄明白了Linux系统进程管理的一些基本概念和编程方法,总结下来以方便大家学习和自己实 ...
随机推荐
- 【原】Storm Tutorial
Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...
- 用原生javascript模拟经典FC游戏公路争霸
#用原生javascript模拟经典FC游戏公路争霸 前几天看了园子里面的随笔 [原生javascript开发仿微信打飞机小游戏](http://www.cnblogs.com/Mr-Nobody/p ...
- 转载-MySQL 加锁处理分析
MySQL 加锁处理分析 发表于 2013 年 12 月 13 日 由 hedengcheng 1 背景 1 1.1 MVCC:Snapshot Read vs Current Re ...
- Java设计模式系列之动态代理模式(转载)
代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问. 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念. 代理模式示例代码 public interface Sub ...
- Android实例-程序切换到后台及从后台切换到前台
相关资料: http://www.delphitop.com/html/Android/2933.html 程序包下载: http://download.csdn.net/detail/zhujian ...
- SMTP邮件服务器配置
QQ个人邮箱使用: smtp.qq.com端口为25 密码是个人邮箱密码 QQ企业邮箱使用: smtp.exmail.qq.com端口为25 密码是邮箱密码 163邮箱使用 smtp.163.com端 ...
- memcached全面剖析–2. 理解memcached的内存存储
Slab Allocation机制:整理内存以便重复使用 最近的memcached默认情况下采用了名为Slab Allocator的机制分配.管理内存. 在该机制出现以前,内存的分配是通过对所有记录简 ...
- CentOS 搭建LNMP服务器和LAMP服务器
CentOS 搭建LNMP服务器 方法一:yum安装 1.更新YUM源 wget http://www.atomicorp.com/installers/atomic #下载atomic自动更新Y ...
- uva10474 简单排序查找 一次AC
题目很简单,加上读题20分钟一次AC.还是用到了快排qsort. #include<iostream> #include<cstdlib> using namespace st ...
- 【PYTHON】二维码生成
二维码是什么? 二维码从一维码扩展而来,增加另一维具有可读性的条码,用黑白矩形图形表示二进制数据,被设备扫描后获取其中包含的信息,二维码的长度.宽度均记载着数据,二维码具有定位点和容错机制,即便没有辨 ...