Loading... # 一、代码 test的程序主要是将1-3号线程,绑定在1-3核上 ```cpp #include <stdlib.h> #include <stdio.h> // #include <sys/types.h> // #include <sys/sysinfo.h> #include <unistd.h> #define __USE_GUN // #include <sched.h> // #include <ctype.h> #include <string.h> #include <pthread.h> #define THREAD_MAX_NUM 100// 1个cpu内最多进程数 int num=0; //cpu中核数 void* threadFun(void* arg)// arg传递线程标号,自己定义 { //sleep(2); cpu_set_t mask;// cpu核的集合 cpu_set_t get;// 获取在集合中的cpu int* a=(int*)arg; printf("this is: %d\n",*a);// 打印这是第几个线程 CPU_ZERO(&mask);// 将集合置为空集 CPU_SET(*a,&mask);// 设置亲和力值 if(sched_setaffinity(0,sizeof(cpu_set_t),&mask)==-1)// 设置线程cpu亲和力 { printf("warning: could not set CPU affinity, continuing...\n"); } while(1) { CPU_ZERO(&get); if(sched_getaffinity(0,sizeof(get),&get)==-1)// 获取线程cpu亲和力 { printf("warning: could not get thread affinity, continuing...\n"); } for(int i=0;i<num;++i) { if(CPU_ISSET(i,&get))// 判断线程与哪个cpu有亲和力 { //printf("this thread %d is running processor: %d\n",i,i); int a=1000000*1000000; } } } return NULL; } int main(void) { num=sysconf(_SC_NPROCESSORS_CONF);// 获取核数 pthread_t thread[THREAD_MAX_NUM]; printf("system has %i processor(s).\n",num); int tid[THREAD_MAX_NUM]; for(int i=1;i<4;++i) { //if(i%2==0) //{ tid[i]=i;// 每个线程必须有个tid[i] pthread_create(&thread[i],NULL,threadFun,(void*)&tid[i]); //} //sleep(2); } for(int i=1;i<4;++i) { pthread_join(thread[i],NULL); } return 0; } ``` --- ### **1、代码功能概述** 主要功能是 **创建多个线程,并将每个线程绑定到指定的 CPU 核上运行**,同时通过循环检查线程的 CPU 亲和性(Affinity)。具体步骤如下: 1. **获取 CPU 核数**:通过 `sysconf(_SC_NPROCESSORS_CONF)` 获取系统 CPU 核数。 2. **创建线程**:创建 3 个线程(`i=1,2,3`),每个线程执行 `threadFun` 函数。 3. **设置 CPU 亲和性**:在子线程中,将线程绑定到指定的 CPU 核(通过 `sched_setaffinity`)。 4. **持续检查亲和性**:子线程进入无限循环,反复获取并验证其 CPU 亲和性。 --- ### **2、代码逐段解析** ### **2.1. 头文件与宏定义** ``` #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> #define THREAD_MAX_NUM 100 int num=0; // CPU 核数 ``` - **关键库**:`pthread.h`(线程操作)、`sched.h`(调度相关函数)。 - **宏定义**:`THREAD_MAX_NUM` 定义最大线程数,`num` 存储 CPU 核数。 ### 2.2. 线程函数 `threadFun`* - **关键操作**: - **设置亲和性**:通过 `sched_setaffinity` 将线程绑定到 `a` 指定的 CPU 核。 - **检查亲和性**:通过 `sched_getaffinity` 获取当前线程的 CPU 亲和性,并验证是否生效。 - **问题点**: - **参数传递风险**:`tid[i]` 是栈上数组,线程启动后可能被覆盖,导致参数错误。 - **无限循环**:`while(1)` 会导致线程无法退出,且占用 CPU 资源。 - **无效计算**:`int a=1000000 * 1000000;` 是无效代码,可能为占位符。 ### 2.3. 主函数 `main`* ``` int main() { num = sysconf(_SC_NPROCESSORS_CONF); printf("system has %i processor(s).\n", num); pthread_t thread[THREAD_MAX_NUM]; int tid[THREAD_MAX_NUM]; for (int i=1; i<4; ++i) { tid[i] = i; pthread_create(&thread[i], NULL, threadFun, (void*)&tid[i]); } for (int i=1; i<4; ++i) { pthread_join(thread[i], NULL); } return 0; } ``` - **关键操作**: - **获取 CPU 核数**:`sysconf(_SC_NPROCESSORS_CONF)`。 - **创建线程**:循环创建 3 个线程,传递线程编号 `i` 作为参数。 - **问题点**: - **线程参数风险**:`tid` 数组在主线程中定义,子线程可能读取到错误值(如主线程修改 `tid` 后)。 - **未处理错误**:`pthread_create` 和 `sched_setaffinity` 的返回值未充分检查。 --- ### **3、代码存在的问题** 1. **CPU 亲和性设置错误** - **函数误用**:`sched_setaffinity` 的第一个参数应为线程的 PID,但代码中传入 `0`(表示当前进程),而非线程 ID。正确做法是使用 `pthread_setaffinity_np(pthread_self(), ...)` 。 - **示例修正**: ``` cpu_set_t mask; CPU_ZERO(&mask); CPU_SET(*a, &mask); pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask); ``` 2. **线程参数传递风险** - **数据竞争**:`tid` 数组在主线程中定义,子线程启动后可能被主线程修改。应改用动态内存分配或分离参数传递: ``` int* tid = malloc(sizeof(int)); *tid = i; pthread_create(&thread[i], NULL, threadFun, (void*)tid); ``` 3. **无限循环与资源浪费** - **性能问题**:`while(1)` 导致线程无法退出,且 `CPU_ISSET` 检查占用 CPU 资源。建议添加退出条件或休眠: ``` while (1) { sched_getaffinity(...); sleep(1); // 降低 CPU 占用 } ``` 4. **未处理函数返回值** - **错误忽略**:`pthread_create` 和 `sched_setaffinity` 的返回值未检查,可能导致程序崩溃或行为异常。 --- ### **总结** - **核心功能**:代码尝试将线程绑定到指定 CPU 核,但存在参数传递、函数误用和资源泄漏问题。 - **优化方向**:使用 `pthread_setaffinity_np`、改进参数传递、添加退出机制和降低 CPU 占用。 # 二、测试流程 taskset -c 0 ./test -c命令就是直接将主线程绑定在核0上 最后修改:2025 年 07 月 09 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏