利用管道通信(pipe)测量进程间的上下文切换(context switch)开销

news2024/9/20 12:39:39

利用管道通信(pipe)测量进程间的上下文切换(context switch)开销

《https://pages.cs.wisc.edu/~remzi/OSTEP/cpu-mechanisms.pdf》

Measuring the cost of a context switch is a little trickier. The lmbench benchmark does so by running two processes on a single CPU, and setting up two UNIX pipes between them; a pipe is just one of many ways processes in a UNIX system can communicate with one another. The first process then issues a write to the first pipe, and waits for a read on the second; upon seeing the first process waiting for something to read from the second pipe, the OS puts the first process in the blocked state, and switches to the other process, which reads from the first pipe and then writes to the second. When the second process tries to read from the first pipe again, it blocks, and thus the back-and-forth cycle of communication continues. By measuring the cost of communicating like this repeatedly, lmbench can make a good estimate of the cost of a context switch. You can try to re-create something similar here, using pipes, or perhaps some other communication mechanism such as UNIX sockets.

然后,第一个进程(子进程)向第一个管道发出写操作,并等待第二个管道的读操作;在看到第一个进程等待从第二个管道读取内容时,操作系统会将第一个进程置于阻塞状态,并切换到另一个进程(父进程),后者从第一个管道读取内容,然后向第二个管道写操作。当第二个进程再次尝试从第一个管道中读取数据时,它就会阻塞,这样来回循环的通信就继续进行。

在这里插入图片描述

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <assert.h>

const int N = 1e2 + 10; // Number of iterations for context switches

int main(int argc, char *argv[]) {
    int pipefd[2][2]; // Array to hold two pipes: one for each direction of communication
    char buf; // Buffer to hold the character read from the pipe

    // Check if the correct number of arguments are provided
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <string> <string>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // Create the two pipes
    if (pipe(pipefd[0]) == -1 || pipe(pipefd[1]) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // Fork the process to create a child process
    int rc1 = fork();

    if (rc1 < 0) {
        // Fork failed
        fprintf(stderr, "fork failed\n");
        exit(EXIT_FAILURE);
    } else if (rc1 == 0) { 
        // Child process
        close(pipefd[0][0]); // Close unused read end of the first pipe
        close(pipefd[1][1]); // Close unused write end of the second pipe

        for (int i = 0; i < N; ++i) {
            // Write to the first pipe
            write(pipefd[0][1], argv[1], strlen(argv[1]) + 1);

            // Read from the second pipe
            while (read(pipefd[1][0], &buf, 1) > 0) {
            	// ************
                //write(STDOUT_FILENO, &buf, 1);
                if (buf == '\0') {
                    //write(STDOUT_FILENO, "\n", 1);
                    break;
                }
            }
        }

        // Close the used pipe ends before exiting
        close(pipefd[0][1]);
        close(pipefd[1][0]);
        exit(EXIT_SUCCESS);
    } else {
        // Parent process
        close(pipefd[0][1]); // Close unused write end of the first pipe
        close(pipefd[1][0]); // Close unused read end of the second pipe

        struct timeval start, end;

        // Get the start time
        int rc1 = gettimeofday(&start, NULL);
        for (int i = 0; i < N; ++i) {
            // Read from the first pipe
            while (read(pipefd[0][0], &buf, 1) > 0) {
                // ************
                //write(STDOUT_FILENO, &buf, 1);
                if (buf == '\0') {
                    //write(STDOUT_FILENO, "\n", 1);
                    break;
                }
            }

            // Write to the second pipe
            write(pipefd[1][1], argv[2], strlen(argv[2]) + 1);
        }
        // Get the end time
        int rc2 = gettimeofday(&end, NULL);
        assert(rc1 == 0 && rc2 == 0);

        // Calculate elapsed time
        double elapsed = (double) end.tv_sec + (double) end.tv_usec / 1e6 - ((double) start.tv_sec + (double) start.tv_usec / 1e6);
        // Calculate average context switch time
        double context_switch = elapsed / (2 * N);
		
		printf("Total time: %f seconds\n", elapsed);
        // Print the average context switch time
        printf("Average context switch time: %lf seconds\n", context_switch);

        // Close the used pipe ends
        close(pipefd[1][1]);
        close(pipefd[0][0]);
    }
    return 0;
}

运行结果:

[chap6] :) cc -o contextSwitch contextSwitch.c 
[chap6] :) ./contextSwitch 1111 222222
Total time: 0.010745 seconds
Average context switch time: 0.000049 seconds
[chap6] :) ./contextSwitch 1111 222222
Total time: 0.014709 seconds
Average context switch time: 0.000067 seconds
[chap6] :) ./contextSwitch 1111 222222
Total time: 0.011982 seconds
Average context switch time: 0.000054 seconds
[chap6] :) 

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

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

相关文章

【LabVIEW FPGA入门】NI 环境安装教程

注意&#xff1a;安装软件之前关闭杀毒软件&#xff0c;避免安装时损坏&#xff0c;安装完成在使用杀毒软件。 步骤1&#xff1a;判断自己是否需要LabVIEW 编程。 下面这几种情况可以调过安装LabVIEW&#xff1a; 不需要LabVIEW或其他语言编程&#xff0c;直接在MAX或仪器软面板…

短视频素材该去哪里找?分享8个短视频剪辑必备的素材大全

在短视频创作与运营中&#xff0c;素材的找寻常常成为创作者的最头疼的事&#xff0c;因为它既要求不侵犯版权&#xff0c;又追求内容的优质性。然而&#xff0c;今天我要为大家揭晓一些剪辑短视频素材库的宝藏网站&#xff0c;它们将成为你创作旅程中的得力帮手&#xff0c;让…

动态手势识别(VGG11)

学校的大作业要做一个视频图像处理相关的&#xff0c;就做了动态手势识别 VGG代码 import torch import torch.nn as nnclass VGG_11_3D(nn.Module):def __init__(self, num_classes, pretrainedFalse):super(VGG_11_3D, self).__init__()self.conv1 nn.Conv3d(3, 64, kernel…

猫狗分类识别①将文件夹中图像统一转化为某一固定格式

一、 导入库 pip install Image 二、确保库中存在Image库&#xff0c;可以在Terminal或控制台中查看 pip list 三、图像后缀处理 import os from PIL import Image def convert_to_png(input_folder, output_folder):if not os.path.exists(output_folder):os.makedirs(outp…

虚拟机安装麒麟系统

官网&#xff1a;https://www.kylinos.cn/ 系统&#xff1a;银河麒麟高级服务器操作系统V10&#xff08;Kylin-Server-10-8.2&#xff09; 安装介质&#xff1a;虚拟机 兼容版下载地址&#xff1a; https://distro-images.kylinos.cn:8802/web_pungi/download/share/phHF6x7rta…

一物一码数字化营销进军调味品行业,五丰黎红“星厨俱乐部”火啦!

近日&#xff0c;由五丰黎红联合纳宝科技精心打造的小程序“星厨俱乐部”火啦&#xff01;一经上线就吸引了大量用户注册和参与&#xff0c;可以说取得了非常成功的市场反馈&#xff0c;那究竟是一个什么样的小程序&#xff0c;竟然有这么大的吸引力呢&#xff1f; 介绍小程序之…

【Mysql数据库进阶02】第一范式~第四范式 Normal Form

第一范式~第四范式Normal Form 0 引言1 第一范式2 第二范式3 第三范式4 BC范式5 第四范式总结 0 引言 因为软考&#xff0c;我又重新拾起了数据库&#xff0c;那么到底如何去判断它属于第几范式呢 1 第一范式 设R是一个关系模式&#xff0c;R属于第一范式当且仅当R中每一个…

P8805 [蓝桥杯 2022 国 B] 机房

P8805 [蓝桥杯 2022 国 B] 机房 分析 是一道lca题目&#xff0c;可以直接套模板 前缀和处理点权 具体思路&#xff1a; 1.n台电脑用n-1条网线相连&#xff0c;任意两个节点之间有且仅有一条路径&#xff08;拆分成各自到公共祖先节点的路径——lca&#xff09;&#xff1b;…

MLP的代替:KAN

受柯尔莫哥洛夫-阿诺德表示定理的启发&#xff0c;作者提出柯尔莫哥洛夫-阿诺德网络&#xff08;KAN&#xff09;作为多层感知器&#xff08;MLP&#xff09;有前途的替代品。MLP 在节点&#xff08;“神经元”&#xff09;上具有固定的激活函数&#xff0c;而 KAN 在边&#x…

SAP CS07复制BOM简介

在比较大型的集团公司中会应用到这样一个场景,所有的BOM都是由总部研发统一管控,然后在下发到下属的工厂进行生产,当发生变更的时候BOM也是会随之进行变更。 同样的在相同的两家工厂中,使用的是一套的设计方案,并且当物料发起变更的时候BOM也要随之进行变更处理。 在对BO…

Linux程序开发(一):Linux基础入门安装和实操手册

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

C语言之旅:自定义类型(联合和枚举)

目录 一.联合体 1.1 联合体的声明 1.2 联合体的使用 1.3 为什么输出 4呢&#xff1f; 1.4 相同成员的结构体和联合体对比 1.5 联合体大小对比 1.6使用联合体判断大小端 二.枚举类型 2.1枚举类型的例举&#xff1a; 2.2枚举类型的优点 2.3 枚举类型的使用 在上篇文章中…

如何利用命令提示符列出文件?这里提供了几个实例供你参考

序言 什么命令可以用来列出目录中的文件&#xff1f;如何在命令提示符Windows 10/11中列出文件&#xff1f;很多人对这些问题感到困惑。在这篇文章中&#xff0c;我们详细解释了命令提示符列出文件的主题。 CMD&#xff08;命令提示符&#xff09;是一个功能强大的Windows内置…

Python学习之路 | Python基础语法(二)

Python3 面向对象 封装、继承、多态。 基础 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。方法&#xff1a;类中定义的函数。类变量&#xff1a;类变量在整个实例化的对象中是公用的。类变量定义在类中…

与禹老师学前端vue3学习汇总

24.5.15&#xff1a; 创建Vue3工程 1.确定自己电脑有没有nodejs环境&#xff0c;在cmd中输入node&#xff0c;如果出现Node.js的版本号说明已经有这个环境了&#xff0c;否则搜索Node.js安装 2.先在D盘创建一个文件夹Vue3_Study&#xff0c;然后在这个空文件夹中右键选择终端…

【069】基于SpringBoot+Vue实现的企业资产管理系统

系统介绍 基于SpringBootVue实现的企业资产管理系统管理员功能有个人中心&#xff0c;用户管理&#xff0c;资产分类管理&#xff0c;资产信息管理&#xff0c;资产借出管理&#xff0c;资产归还管理&#xff0c;资产维修管理。用户可以对资产进行借出和归还操作。因而具有一定…

Git系列:Git Switch 高效使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

实时网络监控 - 一目了然网络状况

网络问题排查一直是IT管理员头痛的问题。随着网络规模的不断扩大和业务复杂度的提升&#xff0c;如何快速定位和解决网络故障变得尤为关键。本文详细介绍了一款名为 AnaTraf 的网络流量分析工具,它能提供全流量回溯分析、实时网络监控、性能分析等功能,助力企业快速诊断和解决各…

每日两题 / 236. 二叉树的最近公共祖先 124. 二叉树中的最大路径和(LeetCode热题100)

236. 二叉树的最近公共祖先 - 力扣&#xff08;LeetCode&#xff09; dfs统计根节点到p&#xff0c;q节点的路径&#xff0c;两条路径中最后一个相同节点就是公共祖先 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

鸿蒙 DevEcoStudio:简单实现网络请求登录案例

使用http或axios实现登录案例 在entry/src/main/ets/pages路径下新建Page9.ets文件&#xff1a; import http from ohos.net.http import router from ohos.router Entry Component struct Page9 {State message: string Hello WorldState username: string State password:…