Linux下C语言多线程CPU使用率监控程序编译链接错误求助
C语言多线程CPU使用率程序编译未定义引用问题
编写了一个多线程C程序,用于读取并打印Linux系统所有CPU核心的使用率。单线程状态下运行正常,但改为多线程后,编译时出现大量未定义引用错误,无法定位问题。期望程序实现三个线程循环执行(每次循环休眠1秒),并能通过Ctrl+C正常终止。
原代码文件
头文件(funkctions.h)
#include <pthread.h> extern int cpu_user[16]; extern int cpu_sum[16]; extern float cpu_proc[16]; extern pthread_t t_reader; extern pthread_t t_analyzer; extern pthread_t t_printer; extern pthread_mutex_t mutex_r; extern pthread_mutex_t mutex_a; extern pthread_mutex_t mutex_p; void *reader(); void *analyzer(); void *printer(); //void *logger(); //void *watchdog();
主函数(main.c)
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <signal.h> #include "funkctions.h" void closing(); int main(){ signal(SIGINT, closing); pthread_mutex_init(&mutex_r, NULL); pthread_mutex_init(&mutex_a, NULL); pthread_mutex_init(&mutex_p, NULL); pthread_create(&t_reader, NULL, reader, NULL); pthread_create(&t_analyzer, NULL, analyzer, NULL); pthread_create(&t_printer, NULL, printer, NULL); return 0; } void closing(){ printf("\nCleaning and closing...\n"); pthread_mutex_destroy(&mutex_r); pthread_mutex_destroy(&mutex_a); pthread_mutex_destroy(&mutex_p); pthread_join(t_reader, NULL); pthread_join(t_analyzer, NULL); pthread_join(t_printer, NULL); printf("\nDONE!\n"); exit(0); }
reader函数(reader.c)
#include <stdio.h> #include <string.h> #include <pthread.h> #include <unistd.h> #include "../funkctions.h" int cpu_user[16]; int cpu_sum[16]; void *reader(){ while(1){ pthread_mutex_lock(&mutex_r); char buffer[255]; FILE *pFile; pFile = fopen("/proc/stat", "r"); fgets(buffer, sizeof(buffer), pFile); //discarding 1st line of /proc/stat for(int i = 0; i < 16 ; i++){ //reading lines form 2 do 17 (for 16 cpu cores) int temp = 0; //setting temp to zero for every for loop fgets(buffer, sizeof(buffer), pFile); //reading next line of /proc/stat sscanf(buffer, "%*s %d", &cpu_user[i]); //saving 2nd line of /proc/stat ---> to extern int array char *token = strtok(buffer, " "); //setting token for new buffer while(token != NULL){ //token in NULL when there is nothing more in string to process if (sscanf(token, "%d", &temp) == 1){ //finding next decimal (sscanf returns 1 when it finds a match) cpu_sum[i] += temp; //sum of cpu usage for every core ---> to extern int array } token = strtok(NULL, " "); //going to next part of string when token found } pthread_mutex_unlock(&mutex_r); } fclose(pFile); sleep(1); } }
analyzer函数(analyzer.c)
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include "../funkctions.h" float cpu_proc[16]; void *analyzer(){ while(1){ pthread_mutex_lock(&mutex_a); for(int i = 0; i < 16; i++){ cpu_proc[i] = ((float)cpu_user[i]/(float)cpu_sum[i])*100; } pthread_mutex_unlock(&mutex_a); sleep(1); } }
printer函数(printer.c)
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include "../funkctions.h" void *printer(){ while(1){ pthread_mutex_lock(&mutex_p); printf("\n------------------------------"); for(int i = 0; i < 16 ; i++){ printf("\nCPU%d: %7.2lf%%", i, cpu_proc[i]); } printf("\n------------------------------"); pthread_mutex_unlock(&mutex_p); sleep(1); } }
原编译命令及错误输出
gcc -o main main.c functions_source/analyzer.c functions_source/printer.c functions_source/reader.c -lpthread
错误输出:
/usr/bin/ld: /tmp/cc6dGjI5.o: warning: relocation against `t_printer' in read-only section `.text' /usr/bin/ld: /tmp/cc6dGjI5.o: in function `main': main.c:(.text+0x24): undefined reference to `mutex_r' /usr/bin/ld: main.c:(.text+0x38): undefined reference to `mutex_a' /usr/bin/ld: main.c:(.text+0x4c): undefined reference to `mutex_p' /usr/bin/ld: main.c:(.text+0x6f): undefined reference to `t_reader' /usr/bin/ld: main.c:(.text+0x92): undefined reference to `t_analyzer' /usr/bin/ld: main.c:(.text+0xb5): undefined reference to `t_printer' /usr/bin/ld: /tmp/cc6dGjI5.o: in function `closing': main.c:(.text+0xe2): undefined reference to `mutex_r' /usr/bin/ld: main.c:(.text+0xf1): undefined reference to `mutex_a' /usr/bin/ld: main.c:(.text+0x100): undefined reference to `mutex_p' /usr/bin/ld: main.c:(.text+0x10f): undefined reference to `t_reader' /usr/bin/ld: main.c:(.text+0x123): undefined reference to `t_analyzer' /usr/bin/ld: main.c:(.text+0x137): undefined reference to `t_printer' /usr/bin/ld: /tmp/ccH46vwi.o: in function `analyzer': analyzer.c:(.text+0xf): undefined reference to `mutex_a' /usr/bin/ld: analyzer.c:(.text+0x9b): undefined reference to `mutex_a' /usr/bin/ld: /tmp/ccDXHFL5.o: in function `printer': printer.c:(.text+0xf): undefined reference to `mutex_p' /usr/bin/ld: printer.c:(.text+0x9d): undefined reference to `mutex_p' /usr/bin/ld: /tmp/ccREn7jd.o: in function `reader': reader.c:(.text+0x21): undefined reference to `mutex_r' /usr/bin/ld: reader.c:(.text+0x18c): undefined reference to `mutex_r' /usr/bin/ld: warning: creating DT_TEXTREL in a PIE collect2: error: ld returned 1 exit status
问题解决
1. 未定义引用的核心原因
头文件中用extern声明了互斥量和线程变量,但没有在任何源文件中实际定义这些变量。extern仅告知编译器变量存在,必须在某个文件中分配内存(即定义变量)。
2. 编译错误修复
在main.c中添加全局变量的定义(放在main函数外):
pthread_t t_reader, t_analyzer, t_printer; pthread_mutex_t mutex_r, mutex_a, mutex_p;
3. 逻辑问题修复
- 主线程退出问题:原
main函数直接return 0会导致进程终止,子线程也会被强制结束。修改为主线程进入无限休眠循环:int main(){ // ... 原有代码 while(1) { sleep(1); } } - 互斥量解锁位置错误:原
reader函数把解锁操作放在for循环内部,导致第一次循环后就释放锁,后续读取无保护。将pthread_mutex_unlock(&mutex_r)移到for循环外部。 - CPU数据累加问题:原
reader中cpu_sum[i]未清零,会持续累加历史数据,导致使用率计算失真。每次读取前清零cpu_user[i]和cpu_sum[i]。 - 线程终止问题:原
closing函数直接调用pthread_join无法终止无限循环的线程,添加pthread_cancel取消线程后再等待结束:void closing(){ printf("\nCleaning and closing...\n"); pthread_cancel(t_reader); pthread_cancel(t_analyzer); pthread_cancel(t_printer); pthread_join(t_reader, NULL); pthread_join(t_analyzer, NULL); pthread_join(t_printer, NULL); pthread_mutex_destroy(&mutex_r); pthread_mutex_destroy(&mutex_a); pthread_mutex_destroy(&mutex_p); printf("\nDONE!\n"); exit(0); } - 数据同步问题:
analyzer读取cpu_user和cpu_sum时需要持有mutex_r,避免reader修改数据导致脏读;printer读取cpu_proc时持有mutex_a即可。
4. 最终编译命令
保持原编译命令即可:
gcc -o main main.c functions_source/analyzer.c functions_source/printer.c functions_source/reader.c -lpthread
内容的提问来源于stack exchange,提问作者BartoszOlejarz
相关产品推荐
相关产品推荐

