Linux programming-process/thread-bound CPU-multi-process multi-thread programming
Intro
-----
When writing server code, you can bind the current process to a fixed CPU core or thread to a fixed CPU core to improve the efficiency of the system scheduling program and improve the efficiency of program execution. The complete code is pasted below.
'''
/*************************************** *********
* This routine explains how to bind processes and threads to a fixed cpu core.
* To improve program running efficiency
**************************************** ********/
# Include <unistd. h>
# Ifndef _ USE_GNU
# Define _ USE_GNU // to use macro definitions such as SET_SET (), the unistd. h file seems to have been defined
# Endif
# Include <sched. h>
# Include <pthread. h>
# Include <stdio. h>
# Include <vector>
Unsigned int systemCPUNum ()
{
// _ SC _NPROCESSORS_CONF indicates the number of CPUs, starting from 0.
Return sysconf (_ SC _NPROCESSORS_CONF );
}
Bool currentProcessAffinity (std: vector <unsigned int> & runningCPUVector)
{
Cpu_set_t cpuSet;
// Clear a CPU set
CPU_ZERO (& cpuSet );
// Obtain the CPU to which the specified process ID is bound
Int ret = sched_getaffinity (0, // 0 indicates the current process
Sizeof (cpuSet ),
& CpuSet );
If (ret <0)
{
Return false;
}
Unsigned int cpuNum = systemCPUNum ();
RunningCPUVector. clear ();
For (unsigned int I = 0; I <cpuNum; ++ I)
{
// Check whether a CPU number is in a collection
If (CPU_ISSET (I, & cpuSet ))
{
RunningCPUVector. push_back (I );
}
}
Return true;
}
Bool setCurrentProcessAffinity (const std: vector <unsigned int> & needBindCPUVector)
{
Cpu_set_t cpuSet;
// Clear a CPU set
CPU_ZERO (& cpuSet );
For (auto & iter: needBindCPUVector)
{
CPU_SET (iter, & cpuSet );
}
// Bind the specified process ID to the CPU
Int ret = sched_setaffinity (0, // 0 indicates the current process
Sizeof (cpuSet ),
& CpuSet );
If (ret <0)
{
Return false;
}
Return true;
}
Bool currentThreadAffinity (std: vector <unsigned int> & runningCPUVector)
{
Cpu_set_t cpuSet;
// Clear a CPU set
CPU_ZERO (& cpuSet );
// Obtain the CPU to which the specified Thread ID is bound
Int ret = pthread_getaffinity_np (pthread_self (),
Sizeof (cpuSet ),
& CpuSet );
If (ret <0)
{
Return false;
}
Unsigned int cpuNum = systemCPUNum ();
RunningCPUVector. clear ();
For (unsigned int I = 0; I <cpuNum; ++ I)
{
// Check whether a CPU number is in a collection
If (CPU_ISSET (I, & cpuSet ))
{
RunningCPUVector. push_back (I );
}
}
Return true;
}
Bool setCurrentThreadAffinity (const std: vector <unsigned int> & needBindCPUVector)
{
Cpu_set_t cpuSet;
// Clear a CPU set
CPU_ZERO (& cpuSet );
For (auto & iter: needBindCPUVector)
{
CPU_SET (iter, & cpuSet );
}
// Bind the specified Thread ID to the CPU
Int ret = pthread_setaffinity_np (pthread_self (),
Sizeof (cpuSet ),
& CpuSet );
If (ret <0)
{
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 1;
}
For (auto & iter: runningCPUVector)
{
Printf ("Current process is running at % u CPU \ n", iter );
}
Std: vector <unsigned int> needBindCPUVector {0, 2 };
If (! SetCurrentProcessAffinity (needBindCPUVector ))
{
Printf ("Current process bind CPU failed \ n ");
Return 1;
}
Printf ("Current process bind CPU success \ n ");
RunningCPUVector. clear ();
If (! CurrentProcessAffinity (runningCPUVector ))
{
Printf ("Get current process was bound witch CPU failed \ n ");
Return 1;
}
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 1;
}
For (auto & iter: runningCPUVector)
{
Printf ("Thread % lu is running at % u CPU \ n", pthread_self (), iter );
}
NeedBindCPUVector. clear ();
NeedBindCPUVector. push_back (1 );
If (! SetCurrentThreadAffinity (needBindCPUVector ))
{
Printf ("Current thread bind CPU failed \ n ");
Return 1;
}
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 1;
}
For (auto & iter: runningCPUVector)
{
Printf ("Thread % lu is running at % u CPU \ n", pthread_self (), iter );
}
Return 0;
}
'''
Output result of program execution:
'''
* ***** 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 address for this example: https://github.com/chxuan/samples/blob/master/BindCPU/BindCPU.cpp