C 信号量和线程之间的 "barrier"

标签 c multithreading semaphore

我正在尝试解决我们的操作系统教授在上一次考试中向我们展示的问题,以便为下一次考试做准备。

问题是有两个线程同时执行并且可能在不同的时间内完成。一个特定的线程完成后,它需要阻塞直到另一个线程完成,然后它们才能继续执行。

这在我看来在概念上很简单,但我的代码并没有按照我认为的方式工作。

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

#define N 10

sem_t t_1_sem;
sem_t t_2_sem;

void *thread(void *vargp);
/* shared by both threads*/
struct {
    int count;
} thread_count;

int main() {
    pthread_t tid, tid1;

    thread_count.count = 0;

    sem_init(&t_1_sem, 0, 1);
    sem_init(&t_2_sem, 0, 1);
    printf("Hello from main thread! tid:%ld pid:%d\n", pthread_self(), getpid());
    pthread_create(&tid, NULL, thread, NULL);
    pthread_create(&tid1, NULL, thread, NULL);

    pthread_join(tid, NULL);
    pthread_join(tid1, NULL);

    exit(0);
}

void *thread(void *vargp) {
    int i, tid;

    int val, val2;
    sem_getvalue(&t_1_sem, &val);
    sem_getvalue(&t_2_sem, &val2);
    printf("initial value::: %d : %d\n", val, val2);


    tid = thread_count.count;
    thread_count.count += 1;

    for(i = 0;i<N;i++){
        printf("%d, %d\n", tid, i);
        fflush(stdout);
        //sleep(0.1);
    }

    // TODO
    // barrier
    sem_getvalue(&t_1_sem, &val);
    sem_getvalue(&t_2_sem, &val2);
    printf("second value::: %d : %d\n", val, val2);
    int sem_val;
    if(tid == 0){
        // free other
        sem_getvalue(&t_1_sem, &sem_val);
        printf("posting to 2, waiting on 1 w/ %d count\n", sem_val);
        sem_post(&t_2_sem);
        // wait on this one
        sem_wait(&t_1_sem);
        printf("done waiting on 1\n");
    } else if(tid == 1){
        sem_getvalue(&t_2_sem, &sem_val);
        printf("posting to 1, waiting on 2 w/ %d count\n", sem_val);
        sem_post(&t_1_sem);
        sem_wait(&t_2_sem);
        printf("done waiting on 2\n");
    }

    sem_getvalue(&t_1_sem, &val);
    sem_getvalue(&t_2_sem, &val2);
    printf("final value::: %d : %d\n", val, val2);
    return NULL;
}

我期望看到的是两个线程都计数到 10,然后两个“最终值”printf 彼此相邻。但是,我看到的是在线程完成计数到 10 后立即打印“最终值”——它似乎没有等待。

我在“发布到 N”printf 中打印的 sem_val 整数也得到了非常奇怪的值,例如:

Hello from main thread! tid:-1606277344 pid:5479
initial value::: 0 : 0
0, 0
initial value::: 0 : 0
1, 0
0, 1
1, 1
0, 2
1, 2
1, 3
1, 4
1, 5
0, 3
1, 6
0, 4
1, 7
0, 5
1, 8
0, 6
1, 9
0, 7
second value::: 0 : 0
posting to 1, waiting on 2 w/ -1809628646 count
0, 8
done waiting on 2
final value::: 0 : 0
0, 9
second value::: 0 : 0
posting to 2, waiting on 1 w/ -1809628646 count
done waiting on 1
final value::: 0 : 0

有什么想法/提示吗?

最佳答案

可能要咨询The Little Book of Semaphores . 3.5 节描述了 Barrier 模式及其正确实现方式。

我知道这并不能直接回答您的问题,但它应该能为您指明正确的方向。

关于C 信号量和线程之间的 "barrier",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1569826/

相关文章:

检查文件路径是否可读可写

Python:进程/线程监控

c - 如何通过posix命名信号量同步两个进程?

c - 编写一个名为 CalculateOddEven 的 C 函数,它接受一个指向整数 a 和实际整数 b 和 c 的指针

c - 被误解的话题

Java 基本同步线程

java - 具有 Java API 的 linux 范围内的信号量

c - 刚开始使用 p_thread 和信号量,您将如何使用信号量来等待子线程完成? (没有 p_thread 连接)

c - 指向 ANSI C 中定义的空指针的指针吗?

c++ - 与普通变量相比,仅读取原子变量是否有性能差异?