我学到了信号灯的概念.我正在努力将其付诸实施. 我已经试着实施了19个多小时,但我做不到,所以我写信寻求你的帮助.

它判断当前两个线程的进度,就像它对CV所做的那样,如果两个线程都输入了输出,它可以恢复后续操作.

以下是代码的全文. `

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



void *child1(void *arg) {
    printf("child thread 1 entered!\n");
    // call semaphoreshere here

    printf("child thread 1 exits!\n");
    return NULL;
}

void *child2(void *arg) {
    printf("child thread 2: entered!\n");
    // call semaphores here

    printf("child thread 2: exits\n");
    return NULL;
}

int main(int argc, char *argv[]) {
    pthread_t p1, p2;
    printf("parent thread: begin\n");
    // init semaphores here
    // // sem_init(&empty, 0, 0); 
    // // sem_init(&full, 0, 0); //Code tried but not working properly



    pthread_create(&p1, NULL, child1, NULL);
    pthread_create(&p2, NULL, child2, NULL);
    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    printf("parent thread: end\n");
    return 0;
}

` 在代码中仅使用两个信号量,这将try 控制线程的内部执行顺序,以便两个线程都必须输出~~ENTERED消息才能退出.

我想要的执行结果如下.

>>>
parent thread: begin
child thread 1 entered!
child thread 2: entered!
child thread 2: exits
child thread 1 exits!
parent thread: end

>>>
parent thread: begin
child thread 2 entered!
child thread 1: entered!
child thread 1: exits
child thread 2 exits!
parent thread: end

像这样,我只想实现互相监视的角色,看看他们是否已经进入.

如果你能帮忙,我将不胜感激. 谢谢.

推荐答案

您想要做的(在信号量思维中)是:

  • 线程1等待线程2完成后才退出.
  • 线程2等待线程1完成后才退出.

这导致了下面的代码,我对它做了一些修改,因为我不能忍受全局变量.

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

typedef struct SharedContext_tag {
  sem_t t1done;
  sem_t t2done;
} SharedContext_t;

void *child1(void* arg) {
  SharedContext_t* ctx = (SharedContext_t*) arg;
  printf("child thread 1: entered!\n");
  sem_post(&ctx->t1done);
  sem_wait(&ctx->t2done);
  printf("child thread 1 exits!\n");
  return NULL;
}

void *child2(void* arg) {
  SharedContext_t* ctx = (SharedContext_t*) arg;  
  printf("child thread 2: entered!\n");
  sem_post(&ctx->t2done);
  sem_wait(&ctx->t1done);
  printf("child thread 2: exits!\n");
  return NULL;
}

int main(int argc, const char* argv[]) {
  pthread_t p1;
  pthread_t p2;
  SharedContext_t context;
  sem_init(&context.t1done, 0, 0);
  sem_init(&context.t2done, 0, 0);
  printf("parent thread: begin\n");
  pthread_create(&p1, NULL, child1, &context);
  pthread_create(&p2, NULL, child2, &context);
  pthread_join(p1, NULL);
  pthread_join(p2, NULL);
  printf("parent thread: end\n");
  sem_close(&context.t1done);
  sem_close(&context.t2done);
  return 0;  
}

在我的机器上(这里要小心!),输出是所需的:

> ./sema
parent thread: begin
child thread 1: entered!
child thread 2: entered!
child thread 2: exits!
child thread 1 exits!
parent thread: end

为了使其正常工作,您需要链接到实时库Librt.您可以通过在编译命令中添加-pthread来实现这一点.

> clang-13 -g -O0 -pthread -o sema sema.c

C++相关问答推荐

为什么下面的递归基本情况在C中不起作用?

如何将已分配的数组(运行时已知的大小)放入 struct 中?

两个连续的语句是否按顺序排列?

将指针作为参数传递给函数

错误:包含文件时类型名称未知

平均程序编译,但结果不好

在Apple Silicon上编译x86的Fortran/C程序

在Linux上使用vscode和lldb调试用Makefile编译的c代码

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

为什么电路板被循环删除?

为什么GCC-O1优化破解了这个代码,为了一个GameBoy高级只读存储器而修改了VRAM的循环?

C-try 将整数和 struct 数组存储到二进制文件中

有没有办法减少C语言中线程的堆大小?

通过GTK';传递回调参数;s g_signal_connect()导致C中出现意外值

使用 c 中的 write() 函数将非 ASCII 字符写入标准输出

Linux memcpy 限制关键字语法

通过修改c中的合并排序对数组的偶数索引进行排序

可以从指针数组中的值初始化指针吗?

C 程序调用 malloc 导致总线错误?

M1 Mac 上的 jmp_buf 如何解码?