MIT XV6 - 1.3 Lab: Xv6 and Unix utilities - primes

接上文 MIT XV6 - 1.2 Lab: Xv6 and Unix utilities - pingpong

primes

继续实验,实验介绍和要求如下 (原文链接 译文链接) :

Write a concurrent prime sieve program for xv6 using pipes and the design illustrated in the picture halfway down this page and the surrounding text. This idea is due to Doug McIlroy, inventor of Unix pipes. Your solution should be in the file user/primes.c.

Your goal is to use pipe and fork to set up the pipeline. The first process feeds the numbers 2 through 35 into the pipeline. For each prime number, you will arrange to create one process that reads from its left neighbor over a pipe and writes to its right neighbor over another pipe. Since xv6 has limited number of file descriptors and processes, the first process can stop at 35.

Some hints:

  • Be careful to close file descriptors that a process doesn’t need, because otherwise your program will run xv6 out of resources before the first process reaches 35.
  • Once the first process reaches 35, it should wait until the entire pipeline terminates, including all children, grandchildren, &c. Thus the main primes process should only exit after all the output has been printed, and after all the other primes processes have exited.
  • Hint: read returns zero when the write-side of a pipe is closed.
  • It’s simplest to directly write 32-bit (4-byte) ints to the pipes, rather than using formatted ASCII I/O.
  • You should create the processes in the pipeline only as they are needed.
  • Add the program to UPROGS in Makefile.

大致意思呢,参考 Unix pipes的创造者,大佬Doug McIlroy的 Bell Labs and CSP Threads,基于多进程和管道来筛选一定范围内的素数.

在这里插入图片描述
什么意思呢,每个进程呢就像一个过滤器,把自己处理不了的数据扔给下一级,我是这么理解的啊,这样可能更符合这个实验?

地铁路上想好了怎么写,回来一遍过

/** Prime Number Sieve using Pipes* * This program implements the Sieve of Eratosthenes algorithm using pipes and processes* to find prime numbers concurrently. The algorithm works as follows:* * 1. Each process represents a prime number and filters out its multiples* 2. Numbers are passed through pipes between processes* 3. Each process reads numbers from its left pipe and writes non-multiples to its right pipe* * Process Communication Flow:* * Process 1 (2) -> Process 2 (3) -> Process 3 (5) -> Process 4 (7) -> ...*    [pipe1]         [pipe2]         [pipe3]          [pipe4]* * Each process:* 1. Reads numbers from left pipe* 2. If number is not divisible by its prime, passes it to right pipe* 3. Creates new child process for first number it receives* * Example flow for numbers 2-10:* * Time   Process 1    Process 2    Process 3    Process 4* ---------------------------------------------------------* t0      reads 2      -            -            -* t1      sends 3      reads 3      -            -* t2      sends 5      sends 5      reads 5      -* t3      sends 7      sends 7      sends 7      reads 7* t4      sends 9      reads 9      -            -* * Note: Numbers 4, 6, 8, 10 are filtered out by Process 1 (multiples of 2)*       Numbers 9 is filtered out by Process 2 (multiple of 3)*       Only prime numbers reach their corresponding processes*/#include "kernel/types.h"
#include "user/user.h"// Constants for prime number calculation
#define START_PRIME 2        // First prime number to start with
#define MAX_PRIMES 35       // Maximum number to check for primes// Pipe file descriptor constants
#define PIPE_INVALID -1      // Invalid pipe descriptor
#define PIPE_READ 0          // Read end of pipe
#define PIPE_WRITE 1         // Write end of pipe/*** Prints a prime number to the console* @param n The prime number to print*/
void print_prime(int n) { printf("prime %d\n", n); }/*** Safely closes a pipe file descriptor if it's valid* @param p The pipe file descriptor to close*/
void close_pipe_if_valid(int p) {if (p != PIPE_INVALID) {close(p);}
}/*** Delivers a number through the pipe system and creates new processes for primes* @param n The number to process* @param pipe_left The left pipe for receiving numbers*/
void deliver_prime(int n, int pipe_left[2]) {// If pipe is not initialized, create it and fork a new processif (pipe_left[PIPE_WRITE] == PIPE_INVALID) {int ret = pipe(pipe_left);if (ret < 0) {exit(1);}ret = fork();if (ret == 0) {// Child processclose_pipe_if_valid(pipe_left[PIPE_WRITE]);// Print the prime number this process representsprint_prime(n);// Initialize right pipe for passing numbers to next processint pipe_right[2] = {PIPE_INVALID, PIPE_INVALID};int received_number = 0;// Read numbers from left pipe and filter themwhile (read(pipe_left[PIPE_READ], &received_number,sizeof(received_number)) > 0) {// Skip numbers that are multiples of current primeif (received_number % n == 0) {continue;}// Pass non-multiples to next processdeliver_prime(received_number, pipe_right);}// Clean up pipesclose_pipe_if_valid(pipe_left[PIPE_READ]);close_pipe_if_valid(pipe_right[PIPE_READ]);close_pipe_if_valid(pipe_right[PIPE_WRITE]);// Wait for child process to completewait(0);exit(0);} else if (ret > 0) {// Parent process continues} else {printf("fork error, current index: %d\n", n);exit(1);}} else {// printf("deliver_prime: %d\n", n);// Write number to pipeif (write(pipe_left[PIPE_WRITE], &n, sizeof(n)) <= 0) {exit(1);}}
}/*** Main function that initiates the prime number calculation* @param argc Number of command line arguments* @param argv Command line arguments* @return 0 on successful execution*/
int main(int argc, char *argv[]) {// Initialize pipe for first processint p[2] = {PIPE_INVALID, PIPE_INVALID};// Print the first prime numberprint_prime(START_PRIME);// Process numbers from START_PRIME + 1 to MAX_PRIMESfor (int i = START_PRIME + 1; i <= MAX_PRIMES; i++) {// Skip multiples of START_PRIMEif (i % START_PRIME == 0) {continue;}// Process the number through the pipe systemdeliver_prime(i, p);}// Clean up pipesclose(p[PIPE_READ]);close(p[PIPE_WRITE]);// Wait for child process to completewait(0);return 0;
}

实验结果

make qemu
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0xv6 kernel is bootinghart 1 starting
hart 2 starting
init: starting sh
$ primes
prime 2
prime 3
prime 5
prime 7
prime 11
prime 13
prime 17
prime 19
prime 23
prime 29
prime 31

他实验中提到一点 Since xv6 has limited number of file descriptors and processes, the first process can stop at 35.,于是我把 MAX_PRIMES改成了100并加了一些错误日志,试一下什么时候会"资源耗尽"。

make qemu
qemu-system-riscv64 -machine virt -bios none -kernel kernel/kernel -m 128M -smp 3 -nographic -global virtio-mmio.force-legacy=false -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0xv6 kernel is bootinghart 2 starting
hart 1 starting
init: starting sh
$ primes
prime 2
prime 3
prime 5
prime 7
prime 11
prime 13
prime 17
prime 19
prime 23
prime 29
prime 31
prime 37
prime 41
pipe error, current index: 43
$ 

为什么是43?留个坑吧…

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

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

相关文章

hive两个表不同数据类型字段关联引发的数据倾斜

不同数据类型引发的Hive数据倾斜解决方案 #### 一、‌原因分析‌ 当两个表的关联字段存在数据类型不一致时&#xff08;如int vs string、bigint vs decimal&#xff09;&#xff0c;Hive会触发隐式类型转换引发以下问题&#xff1a; ‌Key值的精度损失‌&#xff1a;若关联字…

【JAVA】业务系统订单号,流水号生成规则工具类

设计业务系统订单号&#xff0c;流水号注意事项 唯一性&#xff1a;确保在分布式环境下ID不重复 有序性&#xff1a;ID随时间递增&#xff0c;有利于数据库索引性能 可读性&#xff1a;包含时间信息&#xff0c;便于人工识别 扩展性&#xff1a;支持业务前缀和类型区分 性能…

【嵌入式开发-SPI】

嵌入式开发-SPI ■ SPI简介■ SPI &#xff08;Standard SPI&#xff09;■ DSPI &#xff08;Dual SPI&#xff09;■ QSPI是 Queued SPI的简写 ■ SPI简介 SPI协议其实是包括&#xff1a;Standard SPI、Dual SPI和Queued SPI三种协议接口&#xff0c;分别对应3-wire, 4-wire…

基于HTTP头部字段的SQL注入:SQLi-labs第17-20关

前置知识&#xff1a;HTTP头部介绍 HTTP&#xff08;超文本传输协议&#xff09;头部&#xff08;Headers&#xff09;是客户端和服务器在通信时传递的元数据&#xff0c;用于控制请求和响应的行为、传递附加信息或定义内容类型等。它们分为请求头&#xff08;Request Headers&…

基于Qt开发的http/https客户端

成果展示&#xff1a; 使用Qt开发HTTP客户端主要依赖QNetworkAccessManager、QNetworkRequest和QNetworkReply三大核心类。以下是具体实现要点及最佳实践&#xff1a; 一、核心类与基础流程​​ 1.QNetworkAccessManager​​ 作为HTTP请求的管理者&#xff0c;负责异步处理…

自适应蒙特卡洛定位-AMCL

自适应蒙特卡洛定位&#xff0c;简称AMCL&#xff0c;主要提供定位功能并以/tf形式输出 蒙特卡洛算法的基本思想&#xff1a;当所要求的问题是某种事件出现的概率或者是某个变量的期望值时&#xff0c;它们可以通过某种"试验"的方法&#xff0c;得到这种事件出现的概…

鲁滨逊归结原理详解:期末考点+解题指南

1. 引言 归结原理&#xff08;Resolution Principle&#xff09; 是自动定理证明和逻辑推理的核心技术&#xff0c;由约翰艾伦罗宾逊&#xff08;John Alan Robinson&#xff09;于1965年提出。它是一阶谓词逻辑的机械化推理方法&#xff0c;广泛应用于人工智能&#xff08;如…

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1商用服务开通教程以及模型体验

在当今数字化浪潮迅猛推进的时代&#xff0c;云计算与人工智能技术的深度融合正不断催生出众多创新应用与服务&#xff0c;为企业和个人用户带来了前所未有的便利与发展机遇。本文将重点聚焦于在华为云这一行业领先的云计算平台上&#xff0c;对 DeepSeek-V3/R1 商用服务展开的…

Matlab基于PSO-MVMD粒子群算法优化多元变分模态分解

Matlab基于PSO-MVMD粒子群算法优化多元变分模态分解 目录 Matlab基于PSO-MVMD粒子群算法优化多元变分模态分解效果一览基本介绍程序设计参考资料效果一览 基本介绍 PSO-MVMD粒子群算法优化多元变分模态分解 可直接运行 分解效果好 适合作为创新点(Matlab完整源码和数据),以包…

自然语言处理NLP中的连续词袋(Continuous bag of words,CBOW)方法、优势、作用和程序举例

自然语言处理NLP中的连续词袋&#xff08;Continuous bag of words&#xff0c;CBOW&#xff09;方法、优势、作用和程序举例 目录 自然语言处理NLP中的连续词袋&#xff08;Continuous bag of words&#xff0c;CBOW&#xff09;方法、优势、作用和程序举例一、连续词袋( Cont…

商业模式解密:鸣鸣很忙下沉市场的隐忧,破局之路在何方?

文 | 大力财经 作者 | 魏力 在零售行业的版图中&#xff0c;“鸣鸣很忙”凭借独特的商业模式&#xff0c;在下沉市场异军突起&#xff0c;成为不可忽视的力量。555亿GMV、广泛的县域覆盖以及高比例的乡镇门店&#xff0c;无疑彰显了其在下沉市场的王者地位。然而&#xff0c;…

YOLOv5推理代码解析

代码如下 import cv2 import numpy as np import onnxruntime as ort import time import random# 画一个检测框 def plot_one_box(x, img, colorNone, labelNone, line_thicknessNone):"""description: 在图像上绘制一个矩形框。param:x: 框的坐标 [x1, y1, x…

CATIA高效工作指南——常规配置篇(二)

一、结构树&#xff08;Specification Tree&#xff09;操作技巧精讲 结构树是CATIA设计中记录模型历史与逻辑关系的核心模块&#xff0c;其高效管理直接影响设计效率。本节从基础操作到高级技巧进行系统梳理。 1.1 结构树激活与移动 ​​激活方式​​&#xff1a; ​​白线…

批量重命名bat

作为一名程序员&#xff0c;怎么可以自己一个个改文件名呢&#xff01; Windows的批量重命名会自动加上括号和空格&#xff0c;看着很不爽&#xff0c;写一个bat处理吧&#xff01;❥(ゝω・✿ฺ) 功能&#xff1a;将当前目录下的所有文件名里面当括号和空格都去掉。 用法&…

嵌入式软件开发常见warning之 warning: implicit declaration of function

文章目录 &#x1f9e9; 1. C 编译流程回顾&#xff08;背景&#xff09;&#x1f4cd; 2. 出现 warning 的具体阶段&#xff1a;**编译阶段&#xff08;Compilation&#xff09;**&#x1f9ec; 2.1 词法分析&#xff08;Lexical Analysis&#xff09;&#x1f332; 2.2 语法分…

【人工智能-agent】--Dify中MCP工具存数据到MySQL

本文记录的工作如下&#xff1a; 自定义MCP工具&#xff0c;爬取我的钢铁网数据爬取的数据插值处理自定义MCP工具&#xff0c;把爬取到的数据&#xff08;str&#xff09;存入本地excel表格中自定义MCP工具&#xff0c;把爬取到的数据&#xff08;str&#xff09;存入本地MySQ…

Golang 应用的 CI/CD 与 K8S 自动化部署全流程指南

一、CI/CD 流程设计与工具选择 1. 技术栈选择 版本控制&#xff1a;Git&#xff08;推荐 GitHub/GitLab&#xff09;CI 工具&#xff1a;Jenkins/GitLab CI/GitHub Actions&#xff08;本文以 GitHub Actions 为例&#xff09;容器化&#xff1a;Docker Docker Compose制品库…

网络基础1(应用层、传输层)

目录 一、应用层 1.1 序列化和反序列化 1.2 HTTP协议 1.2.1 URL 1.2.2 HTTP协议格式 1.2.3 HTTP服务器示例 二、传输层 2.1 端口号 2.1.1 netstat 2.1.2 pidof 2.2 UDP协议 2.2.1 UDP的特点 2.2.2 基于UDP的应用层…

基于大模型预测的吉兰 - 巴雷综合征综合诊疗方案研究报告大纲

目录 一、引言(一)研究背景(二)研究目的与意义二、大模型预测吉兰 - 巴雷综合征的理论基础与技术架构(一)大模型原理概述(二)技术架构设计三、术前预测与手术方案制定(一)术前预测内容(二)手术方案制定依据与策略四、术中监测与麻醉方案调整(一)术中监测指标与数…

【言语】刷题2

front&#xff1a;刷题1 ⭐ 前对策的说理类 题干 新时代是转型关口&#xff0c;要创新和开放&#xff08;前对策&#xff09;创新和开放不能一蹴而就&#xff0c;但是对于现代化很重要 BC片面&#xff0c;排除 A虽然表达出了创新和开放很重要&#xff0c;体现了现代化&#xf…