You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

线程同步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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:53:43