Linux下调用sem_init初始化信号量出现报错问题求助
问题根因
你的编译报错由1个核心语法错误导致,另外还有1个编译时需要注意的链接选项问题:
- 语法错误:C语言全局作用域(所有函数外部)仅允许编写变量声明、常量初始化语句,不能直接放置可执行的函数调用。你将
sem_init(&mutex,0,1);写在了全局变量定义区,这是运行时才会执行的函数逻辑,放在此处会直接触发编译器语法报错,和你截图中的报错信息完全对应。 - 链接注意事项:Linux下使用POSIX信号量、pthread线程库时,编译命令必须附加
-pthread参数,否则会触发链接阶段的未定义引用错误。
修正方法
- 删除全局作用域下的
sem_init(&mutex,0,1);语句 - 将信号量初始化逻辑移动到
main函数内部,放在创建线程的代码之前执行 - (编码规范补充)给线程函数
Count末尾补充return NULL;匹配其void*返回值类型,避免编译器警告;程序退出前调用sem_destroy销毁信号量,释放内核资源。
修正后完整代码
#include <stdio.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> #include <stdlib.h> #define NITER 1000000 int cnt = 0; sem_t mutex; void * Count(void * a) { int i, tmp; for(i = 0; i < NITER; i++) { sem_wait(&mutex); tmp = cnt; /* 拷贝全局cnt到局部变量 */ tmp = tmp+1; /* 局部变量自增 */ cnt = tmp; /* 将局部计算结果写回全局cnt */ sem_post(&mutex); } return NULL; } int main(int argc, char * argv[]) { pthread_t tid1, tid2; // 信号量初始化移至main函数内,线程创建前执行 sem_init(&mutex, 0, 1); if(pthread_create(&tid1, NULL, Count, NULL)) { printf("\n ERROR creating thread 1"); exit(1); } if(pthread_create(&tid2, NULL, Count, NULL)) { printf("\n ERROR creating thread 2"); exit(1); } if(pthread_join(tid1, NULL)) /* 等待线程1执行完成 */ { printf("\n ERROR joining thread"); exit(1); } if(pthread_join(tid2, NULL)) /* 等待线程2执行完成 */ { printf("\n ERROR joining thread"); exit(1); } if (cnt < 2 * NITER) printf("\n BOOM! cnt is [%d], should be %d\n", cnt, 2*NITER); else printf("\n OK! cnt is [%d]\n", cnt); sem_destroy(&mutex); // 销毁信号量释放资源 pthread_exit(NULL); }
编译运行命令
使用如下命令即可正常编译,不会再触发报错:gcc sem_demo.c -o sem_demo -pthread
编译完成后执行./sem_demo即可运行程序,信号量会正确保护全局计数器的自增操作,最终输出符合预期的OK! cnt is [2000000]结果。
内容的提问来源于stack exchange,提问作者Mrcfreeman
相关产品推荐
相关产品推荐

