贪睡的卡比兽 2024-03-19 23:05 采纳率: 54.5%
浏览 9

司机 售货员操作系统死锁

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#include<sys/wait.h>

sem_t start;
sem_t mid;
sem_t end;

void driver_behavior() {
    sem_wait(&start);   //阻塞自己,等待conductor通知
    printf("司机启动汽车!\n");
    printf("汽车行驶中!\n");
    sem_post(&mid); //通知conductor售票
    sleep(2);
    printf("司机停车\n");
    sem_post(&end); //通知conductor开门
}

void conductor_behavior() {
    printf("售货员开始关门!\n");
    sem_post(&start);   // 通知driver
    sem_wait(&mid);     // 阻塞自己直到driver通知
    printf("售票员开始售票!\n");
    printf("售票中!\n");
    sleep(1);
    sem_wait(&end); //阻塞自己直到driver通知
    printf("售货员开门!\n");
}
int main() {
    pid_t driver_pid, conductor_pid;
    //初始化
    sem_init(&start, 1, 0);
    sem_init(&mid, 1, 0);
    sem_init(&end, 1, 0);

    // 创建司机进程
    driver_pid = fork();
    if (driver_pid == -1) {
        perror("Failed to create driver process");
        exit(EXIT_FAILURE);
    }

    if (driver_pid == 0) { // 司机进程
        driver_behavior();
        exit(EXIT_SUCCESS);
    }

    // 创建售票员进程
    conductor_pid = fork();
    if (conductor_pid == -1) {
        perror("Failed to create conductor process");
        exit(EXIT_FAILURE);
    }

    if (conductor_pid == 0) { // 售票员进程
        conductor_behavior();
        exit(EXIT_SUCCESS);
    }

    // 等待子进程结束
    int status;
    if (waitpid(driver_pid, &status, 0) == -1) {
        perror("Error waiting for driver process");
    }
    if (waitpid(conductor_pid, &status, 0) == -1) {
        perror("Error waiting for conductor process");
    }

    // 销毁信号量
    sem_destroy(&start);
    sem_destroy(&mid);
    sem_destroy(&end);

    return 0;
}

  • 写回答

4条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-19 23:06
    关注
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    这段代码是一个简单的进程间通信的例子,使用了信号量来实现进程之间的同步和互斥。 具体而言,代码中创建了两个进程,分别是“司机”和“售票员”,并且它们之间需要进行协作才能完成一次发车的过程。具体的流程如下:
    1. 司机进程先通过sem_wait(&start)函数来阻塞自己,等待售票员进程的通知,表示售票员已经准备好了。
    2. 售票员进程通过sem_post(&start)函数来通知司机进程,表示售票员已经准备好了。
    3. 司机进程收到通知后,就可以进行发车前的准备操作,比如检查油量、刹车等。
    4. 准备完成后,司机进程再通过sem_post(&mid)函数来通知售票员进程,表示司机已经可以开始行驶了。
    5. 售票员进程收到通知后,就可以开始检票售票。
    6. 行驶过程中,司机进程不会再进行通信操作。
    7. 当司机进程到达目的地,经过sem_post(&end)函数来通知售票员进程,表示已经停车并且可以开门了。
    8. 售票员进程收到通知后,就开始开门并且结束本次发车过程。 需要注意的是,进程之间的通信需要保证同步和互斥,否则可能会出现一些不可预期的结果。在这个例子中,定义了三个信号量,分别是start、mid和end,用来控制不同的阶段。另外,在使用sem_wait和sem_post函数时,需要保证信号量的值已经初始化,否则可能会出现卡死的情况。因此,在代码中使用了sem_init函数来进行信号量的初始化。 下面是一个简单的案例说明,假如售货员需要先通知司机才能开始工作,司机完成工作后再通知售货员,整个过程需要进行同步和互斥。 代码如下:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <semaphore.h>
    #include <sys/wait.h>
    sem_t start;
    sem_t end;
    void driver() {
        sem_wait(&start);
        printf("司机:已收到售货员的通知,开始驾驶\n");
        sleep(3);
        printf("司机: 到达目的地,通知售货员\n");
        sem_post(&end);
    }
    void conductor() {
        printf("售货员:通知司机先驾驶\n");
        sem_post(&start);
        sem_wait(&end);
        printf("售货员:司机已到达目的地,开始工作\n");
    }
    int main() {
        sem_init(&start, 0, 0);
        sem_init(&end, 0, 0);
        pid_t driver_pid, conductor_pid;
        driver_pid = fork();
        if (driver_pid == -1) {
            perror("Failed to create driver process");
            exit(EXIT_FAILURE);
        }
        if (driver_pid == 0) {
            driver();
            exit(EXIT_SUCCESS);
        }
        conductor_pid = fork();
        if (conductor_pid == -1) {
            perror("Failed to create conductor process");
            exit(EXIT_FAILURE);
        }
        if (conductor_pid == 0) {
            conductor();
            exit(EXIT_SUCCESS);
        }
        int status;
        if (waitpid(driver_pid, &status, 0) == -1) {
            perror("Error waiting for driver process");
        }
        if (waitpid(conductor_pid, &status, 0) == -1) {
            perror("Error waiting for conductor process");
        }
        sem_destroy(&start);
        sem_destroy(&end);
        return 0;
    }
    

    在这个案例中,售货员需要先通知司机开始行驶,司机完成后再通知售货员开始工作。 我们定义了两个信号量,start和end,用来实现进程之间的同步。在driver函数中,司机进程通过sem_wait(&start)函数来阻塞自己等待售货员的通知,然后打印一条日志,表示司机已经收到了售货员的通知,并开始行驶。接着,司机进程再通过sem_post(&end)函数来通知售货员,表示已经到达目的地。 在conductor函数中,售货员进程先打印一条日志,表示已经通知司机开始行驶。然后,售货员进程通过sem_post(&start)函数来通知司机开始行驶,并且通过sem_wait(&end)函数来等待司机的通知,表示已经到达目的地。当售货员收到司机的通知后,就可以打印一条日志,表示开始工作了。 最后,在主函数中创建了司机进程和售货员进程,并等待它们的结束。在这个例子中,其实售货员的工作可以在司机进程完成后才开始,因此并不需要等待售货员进程结束,但是为了演示进程间的同步过程,我们还是等待了售货员进程的结束。 运行上述代码,可以得到如下的输出结果:

    售货员:通知司机先驾驶
    司机:已收到售货员的通知,开始驾驶
    司机: 到达目的地,通知售货员
    售货员:司机已到达目的地,开始工作
    
    评论

报告相同问题?

问题事件

  • 创建了问题 3月19日

悬赏问题

  • ¥300 寻抓云闪付tn组成网页付款链接
  • ¥15 请问Ubuntu要怎么安装chrome呀?
  • ¥15 视频编码 十六进制问题
  • ¥15 Xsheii7我安装这个文件的时候跳出来另一个文件已锁定文件的无一部分进程无法访问。这个该怎么解决
  • ¥15 unity terrain打包后地形错位,跟建筑不在同一个位置,怎么办
  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题