常考计算机操作系统面试习题(四)

目录

[1. Peterson 算法伪代码](#1. Peterson 算法伪代码)

[2. 信号量生产者消费者问题分析](#2. 信号量生产者消费者问题分析)

[3. 注释 Peterson 主函数并分析输出结果](#3. 注释 Peterson 主函数并分析输出结果)

[4. 用 fork 创建子进程的程序](#4. 用 fork 创建子进程的程序)


1. Peterson 算法伪代码

题目:

写出 Peterson 算法的伪代码。

参考答案:

复制代码
// 定义变量
boolean flag[2];     // 表示每个线程是否希望进入临界区
int turn;            // 表示轮到哪个线程进入临界区

// 线程 i 的代码
do {
    flag[i] = true;  // 表示线程 i 希望进入临界区
    turn = j;        // 将权利让给线程 j
    while (flag[j] && turn == j) {
        // 等待线程 j 完成临界区
    }
    // 临界区
    // ...
    flag[i] = false; // 离开临界区
    // 剩余区
    // ...
} while (true);

说明:

Peterson 算法是用于两个线程的同步算法,保证了互斥和死锁避免。

  • flag[i] 表示线程 i 是否希望进入临界区。

  • turn 变量表示当前轮到哪个线程进入临界区,确保不会发生竞争条件。

2. 信号量生产者消费者问题分析

题目:

注释以下代码,并说明三个信号量的含义,以及 A 和 B 哪个是生产者进程,哪个是消费者进程。

复制代码
semaphore full = 0, empty = n, mutex = 1;

A: 
do {
    ... produce an item in nextp ...
    wait(empty);
    wait(mutex);
    add nextp to buffer;
    signal(mutex);
    signal(full);
} while (1);

B: 
do {
    wait(full);
    wait(mutex);
    ... remove an item from buffer to nextc ...
    signal(mutex);
    signal(empty);
    ... consume the item in nextc ...
} while (1);

参考答案:

注释代码:

复制代码
semaphore full = 0;    // 表示缓冲区中的产品数,初始值为 0。
semaphore empty = n;   // 表示缓冲区的空位数,初始值为 n(缓冲区大小)。
semaphore mutex = 1;   // 用于实现对缓冲区操作的互斥访问,初始值为 1。

进程 A 是生产者:

  • produce an item in nextp; 生产一个产品并将其存储在 nextp。

  • wait(empty); 确保缓冲区有空位可以存放新产品。

  • wait(mutex); 确保对缓冲区的互斥访问。

  • add nextp to buffer; 将产品添加到缓冲区。

  • signal(mutex); 释放对缓冲区的互斥访问。

  • signal(full); 增加缓冲区中产品的计数。

进程 B 是消费者:

  • wait(full); 确保缓冲区中有可供消费的产品。

  • wait(mutex); 确保对缓冲区的互斥访问。

  • remove an item from buffer to nextc; 从缓冲区中取出产品到 nextc。

  • signal(mutex); 释放对缓冲区的互斥访问。

  • signal(empty); 增加缓冲区的空位计数。

  • consume the item in nextc; 消费产品。

3. 注释 Peterson 主函数并分析输出结果

题目:

注释以下 Peterson 主函数的每行程序,并分析程序可能的输出结果。

复制代码
boolean flag[2];
flag[0] = false;
flag[1] = false;
int turn;

do {
    flag[i] = true;
    turn = j;
    while (flag[j] && turn == j) {}
    // 临界区
    flag[i] = false;
    // 剩余区
} while (1);

参考答案:

注释代码:

复制代码
boolean flag[2];        // 定义两个标志位,用于表示线程是否希望进入临界区。
flag[0] = false;        // 初始化标志位,表示线程 0 初始时不希望进入临界区。
flag[1] = false;        // 初始化标志位,表示线程 1 初始时不希望进入临界区。
int turn;               // 定义变量,用于指示当前轮到哪个线程进入临界区。

flag[i] = true;         // 线程 i 表示希望进入临界区。
turn = j;               // 将优先权交给线程 j。
while (flag[j] && turn == j) {}  // 如果线程 j 也希望进入临界区且优先级是 j,则等待。

// 临界区:执行线程 i 的临界区代码。
flag[i] = false;        // 线程 i 退出临界区。

// 剩余区:线程 i 执行非临界区代码。

程序输出分析:

  • Peterson 算法保证了互斥性:只有一个线程能进入临界区,两个线程不会同时进入临界区。

  • 死锁避免 :通过 turn 变量的使用,确保没有线程因互相等待而永远阻塞。

  • 饥饿避免 :因为 turn 变量的轮换机制,确保了每个线程都会有机会进入临界区。

4. 用 fork 创建子进程的程序

题目:

写一个程序,完成以下功能:用 fork 创建子进程,若失败,输出 "failed",程序退出;在子进程中输出 "child";在父进程中等待子进程返回后,输出 "parent"。

参考答案:

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    pid_t fpid;  // 定义进程号变量
    fpid = fork();  // 创建子进程

    if (fpid < 0) {  // fork 返回值小于 0 表示创建失败
        printf("failed\n");
        exit(-1);  // 退出程序
    } else if (fpid == 0) {  // fork 返回值等于 0 表示当前是子进程
        printf("child\n");
    } else {  // fork 返回值大于 0 表示当前是父进程
        wait(NULL);  // 等待子进程结束
        printf("parent\n");
    }

    return 0;
}

程序运行结果:

  • 如果 fork() 成功,输出:

    复制代码
    child
    parent
  • 如果 fork() 失败,输出:

    复制代码
    failed

说明:

  • fork() 用于创建子进程,子进程从 fork() 返回点开始执行。

  • 父进程和子进程的区别是 fork() 的返回值不同。

  • wait() 使父进程等待子进程结束后再继续执行。

配套学习:

面试计算机操作系统解析(一中)-CSDN博客

常考计算机操作系统面试习题(一下)-CSDN博客

常考计算机操作系统面试习题(二)(上)-CSDN博客

常考计算机操作系统面试习题(二)(中)-CSDN博客

常考计算机操作系统面试习题(二)(下)-CSDN博客

常考计算机操作系统面试习题(三上)-CSDN博客

常考计算机操作系统面试习题(三下)-CSDN博客

相关推荐
流浪0013 小时前
Linux系统篇42——线程(七) pthread库管理线程的工作流,从创建到回收
linux·操作系统·线程·线程创建到销毁
云计算练习生7 小时前
什么是 Linux?从 Unix 到开源生态的完整脉络
linux·开源·操作系统·unix
云计算练习生1 天前
什么是上下文切换?进程切换时 CPU 到底在保存什么
linux·服务器·操作系统·进程切换
CS创新实验室3 天前
为什么三台机器就能选出一个“带头大哥“?——Raft 一致性算法,一次讲透
分布式·操作系统
sweet丶3 天前
iOS 为什么没有内存交换分区(swap)
操作系统
我爱cope9 天前
【操作系统 | 计算机硬件:CPU、内存与 I/O 如何支撑操作系统?】
学习·操作系统
NineData9 天前
NineData 与统信服务器操作系统完成兼容认证
数据库·oracle·操作系统·软件·数据库管理工具·ninedata·统信
DataScience_201910 天前
系统|dup2:文件描述符复制的艺术
操作系统
Tairitsu_H10 天前
[Linux系统] 自动化构建make / Makefile | 进度条
linux·操作系统·makefile·make
我爱cope10 天前
【操作系统 | 开篇:什么是操作系统?从裸机到多任务系统】
学习·操作系统