线程同步sem_init函数参数0引发编译错误求助
解决编译错误与线程同步问题
嘿,我来帮你搞定这个编译错误,顺便把线程同步的小问题也修正了!
编译错误的根源
你遇到的error: expected declaration specifiers or ‘...’ before numeric constant错误,是因为你手动声明sem_init函数的时候犯了一个C语言基础错误:函数声明的参数位置必须写类型,不能直接写常量值。
你写的声明是:
int sem_init(sem_t *s,0,unsigned int val);
这里第二个参数直接写了0,但编译器期望的是参数类型(比如int),所以直接报错了。而且更重要的是——你已经包含了semaphore.h头文件,这个头文件里已经有sem_init的标准声明了,完全不需要自己再手动声明一遍!
另外你自定义的P和V函数,其实标准库已经提供了对应的实现:sem_wait就是P操作(获取信号量),sem_post就是V操作(释放信号量),也不需要自己声明。
额外的逻辑问题
除了编译错误,你的代码还有一个会导致同步失效的问题:你把sem_init(&mutex,0,1);放在了创建线程的for循环里面,这意味着每创建一个线程就会重新初始化一次信号量,这会破坏信号量的同步状态,必须把它移到循环外面,只初始化一次。
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <unistd.h> /* Global shared variable */ volatile long cnt = 0; /* Counter */ sem_t mutex; void *thread(void *vargp); int main(int argc, char **argv) { long niters; int i, nthreads; pthread_t tid[1000]; niters = atoi(argv[1]); nthreads = atoi(argv[2]); // 只初始化一次信号量,放在创建线程之前 sem_init(&mutex, 0, 1); for (i = 0; i < nthreads; i++) { pthread_create(&tid[i], NULL, thread, &niters); printf("THREAD %d with tid= %ld CREATED \n", i, tid[i]); } for (i = 0; i < nthreads; i++) { pthread_join(tid[i], NULL); printf("THREAD %d with tid= %ld TERMINATED \n", i, tid[i]); } /* Check result */ if (cnt != (nthreads * niters)) printf("BOOM! cnt=%ld --- RACE CONDITION\n", cnt); else printf("OK cnt=%ld\n", cnt); printf("PRESS CTRL-C to terminate or CTRL-Z to suspend \n"); pause(); exit(0); } /* Thread routine */ void *thread(void *vargp) { long i, niters = *((long *)vargp); for (i = 0; i < niters; i++) { // 用标准的sem_wait替代自定义P操作 sem_wait(&mutex); cnt++; // 用标准的sem_post替代自定义V操作 sem_post(&mutex); } return NULL; }
关键修改点说明
- 移除了手动声明的
sem_init、P、V函数,直接使用semaphore.h提供的标准函数 - 将线程函数里的
P(&mutex)替换为sem_wait(&mutex),V(&mutex)替换为sem_post(&mutex) - 将
sem_init的调用移到创建线程的循环之前,确保信号量只初始化一次 - 补充了必要的头文件(比如
unistd.h用于pause函数,stdlib.h用于atoi和exit)
这样修改后,编译错误会消失,而且线程同步的逻辑也能正确工作,不会出现竞态条件啦!
内容的提问来源于stack exchange,提问作者Ulmasbek Rakhmatullaev
相关产品推荐
相关产品推荐

