c - 为什么信号量不阻塞第二个线程? (C)

标签 c multithreading operating-system pthreads semaphore

我想写一个简单的 C 程序来更好地理解信号量。有两个线程,它们都调用同一个函数。第一个,增加全局变量,第二个线程,减少全局变量。

我试图在第一个线程完成其工作之前阻止第二个线程使用该函数。但我仍然得到错误的答案:-2000。看起来两个线程都有偏移量 -1。我该如何解决这个问题,使输出始终为 0?我认为函数内部的 sem_wait 应该阻塞第二个线程,直到第一个线程结束。因此偏移量应该保持为 1。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define NUM_LOOPS 1000
long long counter = 0;
sem_t sem;
sem_t sem1;
void* counting_thread(void* arg) {
    sem_wait(&sem);
    int offset = *(int*) arg;
    int i;
    for(i = 0; i < NUM_LOOPS; i++){
        //sem_wait(&sem);
        counter += offset;
        printf("offset = %d\n", offset1);


        //sem_post(&sem);
    }
    sem_post(&sem);

    pthread_exit(NULL);
}

int main() {
    sem_init(&sem, 0, 1);

    pthread_t th1;
    int offset = 1;
    pthread_create(&th1, NULL, &counting_thread, &offset);
    //sem_post(&sem1);

    pthread_t th2;
    offset = -1;
    pthread_create(&th2, NULL, &counting_thread, &offset);

    pthread_join(th1, NULL);
    pthread_join(th2, NULL);

    printf("Finnal counter value: %lld\n", counter);
    sem_destroy(&sem);
    return 0;
}

最佳答案

根据 pthread_create man page

Notes See pthread_self(3) for further information on the thread ID returned in *thread by pthread_create(). Unless real-time scheduling policies are being employed, after a call to pthread_create(), it is indeterminate which thread-the caller or the new thread-will next execute.

不能保证下一个执行的是谁。 也许对你来说 main 线程接下来正在执行并在新线程之前将 offset 设置为 -1,使其从 offset 读取更新的值,这是-1


您可以使用条件变量来同步。

例如:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define NUM_LOOPS 1000
long long counter = 0;
sem_t sem;
sem_t sem1;
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER; 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 


void* counting_thread(void* arg) {
    sem_wait(&sem);
    int offset = *(int*) arg;
    pthread_cond_signal(&cond1); 

    int i;
    for(i = 0; i < NUM_LOOPS; i++){
      counter += offset;
        printf("offset = %d\n", offset);

  }
    sem_post(&sem);

    pthread_exit(NULL);
}

int main() {
    sem_init(&sem, 0, 1); 

    int offset = 1;
    pthread_t th1;
    pthread_create(&th1, NULL, &counting_thread, &offset);


    pthread_cond_wait(&cond1, &lock);
    pthread_t th2;
    offset = -1;
    pthread_create(&th2, NULL, &counting_thread, &offset);

    pthread_join(th1, NULL);
    pthread_join(th2, NULL);

    printf("Finnal counter value: %lld\n", counter);
    sem_destroy(&sem);
    return 0;
}

关于c - 为什么信号量不阻塞第二个线程? (C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58687884/

相关文章:

c# - 我可以将 Task.Run 包装在另一个 Task.Run() 下吗?

java - 进程和线程的区别

windows - Hook 线程创建/终止

python - python中的内存地址生成器

c - 为什么这个 "if"语句没有在它应该触发的时候触发?

c++ - 将 SWI-Prolog 连接到 C++ 的问题

c - 在c中工作的运行时数据类型,sizeof如何工作?

c - 在 C 中设置索引变量列表

performance - 为什么/太多日志会影响我的应用程序的性能?

linux - 如何找到在给定时刻运行的 linux 操作系统的进程?