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

问题描述 投票:1回答:1

我想编写一个简单的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;
}

c multithreading operating-system pthreads semaphore
1个回答
0
投票

根据pthread_create man page

注:有关线程ID的更多信息,请参见pthread_self(3)。由pthread_create()在* thread中返回。除非实时调度正在使用策略,在调用pthread_create()之后,它是确定下一步将是哪个线程(调用方或新线程)执行。

不保证下一步将执行谁。也许对您来说,main线程正在执行,并在新线程之前设置offset to -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;
}
© www.soinside.com 2019 - 2024. All rights reserved.