操作系统 复习--实训题

news2025/1/23 10:41:45

一. 简答题(共8题,100分)

1. (简答题)

编程使用fork()函数创建子进程,要求父进程中打印当前进程的 PID 和子进程的 PID,而在子进程中只打印当前进程的 PID。

参考代码:

int main() { 

	pid_t child_pid;
    child_pid = fork();   

    if (child_pid == -1) {
        perror("fork");      

       return 1;
    }    // 子进程返回 0
    if (child_pid == 0) {        

     printf("This is the child process, pid = %d\n", getpid());
    } else {  // 父进程返回子进程的 PID
        printf("This is the parent process, pid = %d, child_pid = %d\n", getpid(), child_pid);
    }    return 0;
}

参考资料
【Linux】——进程创建fork()详解

2. (简答题)

在多线程编程中,为了避免多个线程同时访问共享资源而引起的问题,需要使用信号量(Semaphore)实现线程同步。信号量本质上是一个计数器,它记录某个共享资源可被访问的数量。当一个线程想要获取该共享资源时,需要先尝试获取信号量的锁,若获取成功则可以访问该资源,否则需要等待。而当一个线程释放该共享资源时,需要将信号量的计数器加一,以便其他线程可以进行访问。
阅读代码填空:

#define NUM_THREADS 5

int shared_resource = 0;  // 共享资源sem_t mutex;  // 互斥锁信号量// 线程函数,每个线程对共享资源加 1

void* thread_function(void* arg) 
{   
	int thread_id = *((int*)arg);
    sem_wait(&mutex);  // 获取互斥锁信号量
    printf("Thread %d is accessing the shared resource...\n", thread_id);
    shared_resource++;  // 对共享资源加 1
    printf("Thread %d updated the shared resource to %d\n", thread_id, shared_resource);
    sem_post(&mutex);  // 释放互斥锁信号量
    pthread_exit(NULL);
}

int main() 
{ 
	pthread_t threads[NUM_THREADS];   
	int thread_ids[NUM_THREADS];    int i;
    sem_init(&mutex, 0, 1);  // 初始化互斥锁信号量
    for (i = 0; i < NUM_THREADS; i++) {
        thread_ids[i] = i + 1;
        pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
    }    
   for (i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&mutex);  // 销毁互斥锁信号量
    return 0;
}

画横线的地方就是要考的地方

image.png

参考答案:

试获取信号量的锁,若获取成功则可以访问该资源,否则需要等待。而当一个线程释放该共享资源时,需要将信号量的计数器加一,以便其他线程可以进行访问。

阅读代码填空:
#define NUM_THREADS 5int shared_resource = 0;  // 共享资源sem_t mutex;  // 互斥锁信号量// 线程函数,每个线程对共享资源加 1

void* thread_function(void* arg) 
{   
	int thread_id = *((int*)arg);
    sem_wait(&mutex);  // 获取互斥锁信号量
    printf("Thread %d is accessing the shared resource...\n", thread_id);
    shared_resource++;  // 对共享资源加 1
    printf("Thread %d updated the shared resource to %d\n", thread_id, shared_resource);
    sem_post(&mutex);  // 释放互斥锁信号量
    pthread_exit(NULL);
}

int main() 
{ 
	pthread_t threads[NUM_THREADS];   
	int thread_ids[NUM_THREADS];    int i;

    sem_init(&mutex, 0, 1);  // 初始化互斥锁信号量

    for (i = 0; i < NUM_THREADS; i++) {
        thread_ids[i] = i + 1;
        pthread_create(&threads[i], NULL, thread_function, &thread_ids[i]);
    }    
	for (i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
	}
    sem_destroy(&mutex);  // 销毁互斥锁信号量

    return 0;
}

3. (简答题)

使用 pipe() 函数创建了一个匿名管道,然后通过 fork() 函数创建了一个子进程。父进程向管道中写入字符串 “Hello, world!”,而子进程从管道中读取数据并输出。

参考代码:

#define BUFFER_SIZE 25
int main()
{  
	int fd[2];  
	char write_msg[BUFFER_SIZE] = "Hello, world!";  
	char read_msg[BUFFER_SIZE];  
	pid_t pid;  
	if (pipe(fd) == -1) {  // 创建匿名管道
		fprintf(stderr, "Pipe failed");  
		return 1;
	}
	pid = fork();  // 创建子进程
	if (pid < 0) {  // 创建子进程失败
		fprintf(stderr, "Fork failed");
		return 1;
	} else if (pid == 0) {  // 子进程     
		close(fd[1]);  // 关闭写端口     
		read(fd[0], read_msg, BUFFER_SIZE);  // 从管道中读取数据      
		printf("Child process received message: %s\n", read_msg);
	} else {  // 父进程        
		close(fd[0]);  // 关闭读端口    
    	write(fd[1], write_msg, BUFFER_SIZE);  // 向管道中写入数据   
		printf("Parent process sent message: %s\n", write_msg);
	}    
	return 0;
}

4. (简答题)

生产者消费者问题描述 [1] 生产者消费者问题,也称为有限缓冲问题,是一个经典的多进程同步问题。该问题描述了两个进程之间如何在实际运行时共享固定大小的缓冲区。一个进程是生产者,它生成一些数据并将其放入缓冲区;另一个进程是消费者,它从缓冲区中取出数据并将其处理。由于缓冲区具有固定的大小,因此生产者和消费者必须在缓冲区不满和不空的情况下进行同步。
给出同步条件和算法描述:

同步条件 为了遵守同步条件,生产者和消费者必须遵循以下规则:

生产者只有在缓冲区不满时才能添加数据到缓冲区;
消费者只有在缓冲区不空时才能从缓冲区中取出数据;
生产者在向缓冲区中添加数据后应该将其唤醒消费者进程,以便消费者可以及时处理数据;
消费者在取出数据后应该将其唤醒生产者进程,以便生产者可以及时生成数据。

算法描述

可以用一个数组表示缓冲区。在本算法中,将包含生产者和消费者的程序称为主程序。

主程序:

定义缓冲区数组,初始化缓冲区为空
定义互斥量mutex和信号量full、empty分别表示缓冲区是否满或空
创建消费者线程和生产者线程,启动线程
等待子线程完成后,销毁互斥量和信号量

生产者进程:

生成数据项
若缓冲区满,等待信号量empty
获取互斥锁mutex
将数据项放入缓冲区
释放互斥锁mutex
发送信号量full

消费者进程:

若缓冲区空,等待信号量full
获取互斥锁mutex
取出缓冲区中的数据项
释放互斥锁mutex
发送信号量empty
处理数据项

在这个算法描述中,互斥量和信号量是用于确保线程安全和同步的关键元素。互斥量用于控制对共享资源(缓冲区)的访问,以确保同时只有一个线程能够访问它。信号量用于控制进程之间的同步,并向另一个进程发出信号以指示某些事件已经发生。

参考答案:

while(1){  
    produce an item in nextp; //生产数据  
    P(empty); //(要用什么P一下) //获取空缓冲区单元  
    P(mutex);                 //互斥,进入临界区  
    add nextp to buffer;      //将数据放入缓冲区  
    V(mutex);                 //离开临界区,释放互斥信号量  
    V(full);                  //满缓冲区数加1,相当于放入缓冲区了,让缓冲区的数加1  
}

consumer(){  
	while(1){  
		P(full);//获取满缓冲区单元,如果没有数据就等待  
		P(mutex);//进入缓冲区  
		remove an item from buffer;//从缓冲区取出数据  
		V(mutex);//离开临界区,释放互斥信号量  
		V(empty);//空缓冲区数加1  
    	consume the item;//消费数据  
	}
}

5. (简答题)

实训链接:创建进程选择题

1、画出下列程序的进程树:

#include <stdio.h>
#include <unistd.h>

int main()
{
	fork();
	fork();
	fork();
	fork();
	printf("ok\n");
	return 0;
}

参考:
两个图的答案都正确,推荐手写的这种方法

写法一:
进程树
写法二:
进程树
参考链接:
三个连续的fork形成的进程数树怎么画

2、下面程序执行后输出几个“!”,并说明原因。

#include <stdio.h>
#include <unistd.h>

int main()
{
	int i;
	for(i = 0; i < 2; i++){
        fork();
		printf("!\n");
	}
	return 0;
}

参考:
一共输出 6 个。
 
首先程序一开始,bash产生一个进程 P0 执行此程序,P0 进入程序。
 
当 i=0 时:
fork() 产生一个子进程P1,同时它自己输出一个’!'。P1 继承 P0 的诸如环境变量,P1 首先会输出一个 ‘!’。
 
当 i=1 ,会继续执行 for 循环— P1 先 fork() 出一个子进程 P2,同时再输出一个 ‘!’。
P2 进程为 P1 的子进程,它会复制其父进程P2的指令,变量值,程序调用栈,环境变量,缓冲区等,它会输出一个 ‘!’。
 
此时 P0 进入程序后,当 i=1 时,fork() 产生另一个它的子进程P3,同时输出一个 ‘!’。P3 同样会输出一个 ‘!’。
 
下面是图示
输出
 
参考链接
fork()请问下面的程序一共输出多少个“-”?

6. (简答题)

程序员编程过程中,经常需要进程通信,操作系统提供的进程间通信机制主要包括哪些?

参考答案:
1.管道(Pipe):一种单向通信机制,只能在父子进程或兄弟进程之间使用。
2.命名管道(Named Pipe):类似于管道,但可以在不同进程之间使用。
3.消息队列(Message Queue):可以在不同进程之间传递消息,支持多对多通信。
4.共享内存(Shared Memory):可以在不同进程之间共享同一块物理内存,速度很快。
5.信号量(Semaphore):可以用来控制对共享资源的访问,避免竞争条件的发生。
6.套接字(Socket):可以在不同主机之间进行网络通信。
7.信号(Signal):可以用来通知进程某个事件已经发生。

7. (简答题)

实训链接:进程基础知识

  1. 临界区是指并发进程中涉及共享变量的()。
    A、程序段
    B、管理信息区
    C、公共数据区
    D、信息存储区

  2. 下列有关fork()函数返回值说法错误的是()
    A、函数成功返回时,一次返回两个值,错误返回时为-1
    B、返回值等于0表示子进程
    C、返回值大于0表示父进程
    D、大于0返回值为父进程的PID号

  3. 下面程序的输出是什么()
    A、helloworld
    B、wordhello
    C、hello
    D、不确定

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char** argv){
       if(fork() == 0){
           printf("hello");
       }else{
           printf("world");
       }
       return 0;
    }
    
  4. 下面说法不正确的是( )
    A、管道和命名管道是最早进程间通信机制之一
    B、消息队列是将消息按队列的方式组织成的链表,每个消息都是其中的一个节点
    C、进程创建一般由create函数完成
    D、共享内存和消息都是由Linux内核来管理和分配资源

  5. 关于SIGCHLD信号说法错误的是()
    A、在子进程退出时,会向父进程发送该信号
    B、需要及时处理SIGCHLD防止僵尸进程
    C、SIGCHLD信号的默认处理方式是忽略
    D、由于SIGCHLD信号默认方式是忽略,所以在代码中不需要手动设置SIGCHLD信息的处理方式,也不会产生僵尸进程

  6. 下列哪种通信方式只能用于具有亲缘关系进程之间的通信()
    A、匿名管道
    B、消息队列
    C、共享内存
    D、命名管道

8. (简答题)

实训链接:文件系统基础

  1. 比较文件的差异要用到的命令是以下哪一种?(单选)
    A、diff
    B、cat
    C、wc
    D、head

  2. 存放设备文件的相关文件目录是?(单选)
    A、/dev
    B、/etc
    C、/lib
    D、/bin

  3. rm命令表示什么?(单选)
    A、文件复制命令
    B、移动文件命令
    C、文件内容统计命令
    D、文件删除命令

  4. 在openEuler系统中,用户文件描述符0表示?(单选)
    A、标准输出设备文件描述符
    B、标准输入设备文件描述符
    C、管道文件描述符
    D、标准错误输出设备文件描述符

    注释:
    0是标准输入,1是标准输出,2是标准错误
     
    参考:
    彻底弄懂 Linux 下的文件描述符(fd)

  5. 在使用 mkdir命令创建新的目录时,在其父目录不存在时先创建父目录的选项是?(单选)
    A、-d
    B、-m
    C、-p
    D、-f

  6. 执行命令“chmod o+rw myfile”后,myfile文件的权限变化为?(单选)
    A、所有用户都可读写myfile文件
    B、其他用户可读写myfile文件
    C、同组用户可读写myfile文件
    D、文件所有者读写myfile文件
    用户对象
    权限说明

    参考链接
    Linux chmod命令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623869.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用openlayers加载geoserver发布的arcgis瓦片

openlayers版本&#xff1a;6.5 geoserver版本&#xff1a;2.18.0 1. geoserver发布arcgis瓦片 首先去maven上面找最新的gwc-arcgiscache https://mvnrepository.com/artifact/org.geowebcache/gwc-arcgiscache/1.19.1 把这个jar包下载下来放到目录geoserver/WEB-INF/lib下面…

可扩展性与生态应用:Ardor公链AMA回顾

近日&#xff0c;Jelurida团队工程师Francisco Sarrias做客CryptoWallet.com&#xff0c;分享了一些有关Ardor的话题&#xff1a; Ardor是什么&#xff1f; Ardor是一个旨在提高区块链可扩展性的开源平台&#xff0c;这意味着该项目有助于使区块链网络运行更顺畅&#xff0c;用…

10分钟通过云服务器搭建自己的chatGPT镜像服务

通过云服务器搭建自己的chatGPT镜像服务 前提&#xff1a;需要有自己的API KEY 1 购买云服务器 本教程以阿里云的云服务器为例。 阿里云地址&#xff1a;https://www.aliyun.com/?spm5176.28008736.J_3207526240.1.769d3e4dTtNjuI 进入阿里云官网&#xff0c;选择云服务器ECS进…

精选博客系列|VMware如何实现多云基础设施

私有云&#xff0c;公有云&#xff0c;多云&#xff0c;边缘云… 如今&#xff0c;组织的团队、数据和工作负载分布在各种环境中。毫无疑问&#xff0c;这导致了技术上的复杂性增加、安全风险加剧、成本飙升和云战略不连贯的问题。 “39% 的高管难以在&#xff08;他们的&…

18.4:打印一个字符串的全部排列

打印一个字符串的全部排列 方法一&#xff1a;暴力方法。 //方法一&#xff1a;暴力方法。public static List<String> permutation1(String s) {//str是一个存储字符类型的有序表。ArrayList<Character> str new ArrayList<>();//将字符串中的类型存储在s…

Zookeeper概述

​ ZooKeeper概述 ZooKeeper是什么 zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现&#xff0c;是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。提供了基于类似Unix系统的目录节点树方式的数…

docker 安装 nsq

一. nsq介绍 nsq介绍 NSQ是一个基于Go语言&#xff0c;由bitly公司开源出来的一款简单易用的消息中间件。 官方和第三方开发了众多客户端功能库&#xff0c;如基于HTTP的nsqd、Go客户端go-nsq、Python客户端pynsq、基于Node.js的JavaScript客户端nsqjs、异步C客户端libnsq、J…

JavaSE-02【类型转换和运算符】

第一章&#xff1a;数据类型转换 Java程序中要求参与计算的数据&#xff0c;必须要保证数据类型的一致&#xff0c; 如果数据类型不一致则发生类型的转换1.1 自动转换 自动转换&#xff1a;将取值范围小的类型自动提升为取回范围大的类型 自动类型转换原理&#xff1a;一个i…

MySql锁知识记录积累(一)

1.关于脏读、幻读和不可重复读 脏读&#xff1a;一个事务A读取到了另一个事务B未提交的数据&#xff0c;叫做脏读 不可重复读&#xff1a;事务A被事务B干扰到了&#xff01;在事务A范围内&#xff0c;两个相同的查询&#xff0c;读取同一条记录&#xff0c;却反返回了不同的结…

运行一个新vue项目踩坑

npm install报错了&#xff0c;主要是因为node版本太高了。去node官网&#xff0c;下载低版本的msi后缀的文件&#xff0c;运行安装。在vs code里&#xff0c;npm下载依赖&#xff0c;并运行即可。 1. 无法cnpm cnpm : 无法加载文件 D:\Program Files\nodejs\node_global\cnpm.…

前端放大镜效果实现

放大镜效果实现 放大图片的需求&#xff0c;一般是在原有的渲染之上&#xff0c;额外添加一个放大框&#xff0c;当鼠标在原图上移动&#xff0c;放大框内就以当前的鼠标为中心&#xff0c;局部放大一定范围&#xff0c;在淘宝商城中是常有的实现。下面将用两种实现。 1、使用d…

是德 DSOX1202A示波器技术参数

KEYSIGHT是德科技 lnfiniiVision 1000 X 系列示波器是具有专业级功能的入门级示波器&#xff0c;配备的联网软件可提供远程控制和数据记录等功能。 它集 6 种仪器的功能于一身&#xff0c;属于是德科技智能测试台必备仪器之一。该系列包含 4 款独具特长的仪器&#xff0c;通过同…

5年功能测试要18K,一问三不知,还反过来怼我,真是醉了····

最近看了很多简历&#xff0c;很多候选人年限不小&#xff0c;但是做的都是一些非常传统的项目&#xff0c;想着也不能通过简历就直接否定一个人&#xff0c;何况现在大环境越来 越难&#xff0c;大家找工作也不容易&#xff0c;于是就打算见一见。 在沟通中发现&#xff0c;由…

坚持#第418天~久违了,二维码系统

公司有了一个新客户&#xff0c;这家客户的货物都是用铁架框装的&#xff0c;铁架框长得都一样&#xff0c;不好区分&#xff0c;只能看标签来识别&#xff0c;而且发货时需要一一核对发货单上的交货单号对应的货物&#xff0c;标签上的发货单号必须要一致才行&#xff0c;导致…

【干货】Kali Linux渗透基础知识大全,零基础入门必看!

最近好多朋友问我&#xff1a;不会编程&#xff0c;英语也不好&#xff0c;dos命令也记不住&#xff0c;能学习黑客技术么&#xff1f; 我可以明确告诉大家&#xff0c;可以的&#xff01; 相信每一个少年心中&#xff0c;曾经都有过一个黑客梦&#xff01; 有人觉得黑客霸气…

常用的开源自定义表单有哪几大优势特点?

当前&#xff0c;办公已经进入流程化和自动化的阶段&#xff0c;要想跟随着社会发展&#xff0c;引用开源自定义表单工具可以使办公协作效率得到快速提升&#xff0c;它的灵活、便捷、易操作等特点&#xff0c;使得该表单工具深受当今职场的喜爱&#xff0c;是做好数据管理&…

Flutter 库:强大的下拉刷新上拉加载框架——EasyRefresh

Flutter 库&#xff1a;强大的下拉刷新上拉加载框架——EasyRefresh 文章目录 Flutter 库&#xff1a;强大的下拉刷新上拉加载框架——EasyRefresh一、概述1、简介2、特征3、在线演示4、APK下载5、接口参考 二、官方示例1、默认构造函数2、生成器构造函数3、指示器定位4、使用指…

2023年网络安全HW攻防技术总结(珍藏版)

2022年护网正当时&#xff0c;相信不少网安人都已经进入了状态。 我们都知道&#xff0c; 护网行动 是国家应对网络安全问题所做的重要布局之一。至今已经是7个年头了&#xff0c;很多公司在这时候人手不够&#xff0c;因此不得不招募一些网安人员来参加护网。 红队 扮演攻击…

Linux搭建Java环境——安装JDK

一、上传jdk1.8文件 首先通过Xftp 7软件&#xff0c;将jdk文件传输到Linux上&#xff08;连接和Xshell 7方法相同&#xff0c;软件资源在首页中的下载栏处免费获取&#xff09;当然需要在opt文件夹下先新建jdk的文件夹 二、解压jdk文件 解压完成后可以发现蓝色的jdk1.8的目录生…

Android Studio实现五子棋小游戏

项目目录 一、项目概述二、开发环境三、详细设计1、布局设计2、验证码3、AI人机4、背景音乐 四、运行演示五、项目总结 一、项目概述 五子棋是一种两人对弈的策略型棋类游戏&#xff0c;本次五子棋小游戏具有人机对战和人人对战两种玩法。人机对战可以单人挑战AI&#xff0c;实…