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

利用管道通信(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] :) 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vditor集成于VUE笔记

文章目录 前言一、安装Vditor二、渲染markdown三、options3.1 自建CDN3.2 outline大纲不显示、不跳转问题3.3 upload 图片/视频上传3.4 toolbar提示位置点击事件more中文字 3.5 sv分屏渲染模式隐藏编辑框3.6 after中的insertValue或者setValue 前言 Vditor是一款易于使用的 Ma…

3D Web轻量化引擎HOOPS Communicator如何处理DWG文件中的图纸?

在当今工程设计和建筑领域&#xff0c;数字化技术已经成为不可或缺的一部分。HOOPS Communicator作为一种强大的三维数据可视化工具&#xff0c;被广泛应用于处理各种CAD文件&#xff0c;其中包括AutoCAD的DWG格式。在这篇文章中&#xff0c;我们将探讨HOOPS Communicator是如何…

DRF 跨域问题

【一】说明 CORS&#xff08;跨来源资源共享&#xff0c;Cross-Origin Resource Sharing&#xff09;是一种浏览器技术的规范&#xff0c;旨在解决浏览器同源策略&#xff08;Same-Origin Policy&#xff09;的限制&#xff0c;使得Web服务可以从不同的网域&#xff08;源&…

org.springframework.jdbc.BadSqlGrammarException

Cause: java.sql.SQLSyntaxErrorException: Table ‘web.emp’ doesn’t exist 产生原因&#xff1a;web表找不到&#xff0c;所以可能数据库配置错误 spring.datasource.urljdbc:mysql://localhost:3306/web02 更改完成后运行成功

Web浏览器的兼容性测试需要考虑哪些测试点?

测试web网站兼容性时&#xff0c;可以使用各种测试用例来确保网站在不同浏览器中的良好兼容性。以下是一些常见的兼容性测试用例示例&#xff1a; 1. 页面加载测试&#xff1a; - 确保网站在不同浏览器中正常加载&#xff0c;没有加载错误。 - 检查页面加载时间&#xff0c;…

场景文本检测识别学习 day09(SSM、S4、Mamba、S6)

SSM&#xff08;State Space Model&#xff09; SSM是一个针对连续函数的模型&#xff0c;即输入是连续函数&#xff0c;输出也是连续函数。上图为状态方程和输出方程&#xff0c;其中h(t)是当前时刻的状态&#xff0c;x(t)是当前时刻的输入&#xff0c;h’(t)是下一个时刻的状…

应用TRIZ创新原理解决技术矛盾的步骤是什么样的?

如何在有限的时间和资源下&#xff0c;高效地解决技术矛盾&#xff0c;推动技术的进步和创新呢&#xff1f;答案就隐藏在TRIZ创新原理之中。 首先&#xff0c;我们需要了解什么是TRIZ创新原理。TRIZ&#xff0c;即发明问题解决理论&#xff0c;是一套系统的创新方法论&#xff…

程序验证之Dafny--证明霍尔逻辑的半自动化利器

一、What is Dafny?【来自官网介绍 Dafny 】 1)介绍 Dafny 是一种支持验证的编程语言&#xff0c;配备了一个静态程序验证器。 通过将复杂的自动推理与熟悉的编程习语和工具相结合&#xff0c;使开发者能够编写可证明正确的代码&#xff08;相对于 {P}&#xff33;{Q} 这种…

uniapp微信小程序通过萤石云接入海康摄像机

需求&#xff1a;在uniapp微信小程序上查看海康威视的摄像机监控视频和和操作摄像机拍摄方向 在萤石云接入海康摄像机设备&#xff0c;由于不同品牌设备在不同时间段接入方式可能不一致&#xff0c;具体接入方式查看官方文档或咨询官方客服。 海康摄像机官方客服热线&#xf…

web学习笔记(五十五)

目录 1. 配置代码片段的步骤 2. 条件判断 2.1 v-if、v-else、v-else-if 2.2 v-show 2.3 v-show和v-if的区别 1. 配置代码片段的步骤 在Visual Studio Code中我们可以将常用的代码配置成代码片段&#xff0c;这样就可以在页面上快速输入大段代码了。 &#xff08;1&#…

JavaScript-基本数据类型和变量

基本数据类型 JavaScript支持数字、字符串和布尔值3种基本数据类型 字符串型 字符串型是JavaScript用来表示文本的数据类型&#xff0c;字符串通常由单引号或双引号括起来&#xff0c;如果字符串存在特殊字符&#xff0c;可以用转义字符代替 数字型 数字型也是JavaScript中的基…

pytest教程-46-钩子函数-pytest_sessionstart

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_report_testitemFinished钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_sessionstart钩子函数的使用方法。 pytest_sessionstart 是 Pytest 提供的一个钩子函数&#xff0c…

U盘中毒文件变乱码?揭秘原因与高效恢复方法!

在日常使用U盘的过程中&#xff0c;有时我们会遭遇到一个非常棘手的问题——文件突然出现乱码。当你满怀期待地插入U盘&#xff0c;准备打开某个重要文件时&#xff0c;却发现文件名或内容变成了一堆无法识别的字符&#xff0c;这种心情无异于晴天霹雳。乱码文件不仅影响了我们…

数据结构------二叉树经典习题1

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1判断相同的树 OJ链接 这道题相对简单,运用我们常规的递归写法就能轻松写出 所以我们解题思路应该这样想: 1.如果p为空&#xff0c;q为空&#xff0c;那么就是两颗空树肯定相等 2.如果一个树为空另一棵树不为空那么…

Android 应用开发-实现将公共存储空间内的文件复制到应用的私用存储空间中

一、前言 几个月前&#xff0c;我用Android Studio给公司销售部门的同事开发了一款手机app&#xff0c;让同事们用自己的手机就能进行商品的扫码盘点操作&#xff0c;帮他们提高了工作效率&#xff0c;他们用了一段时间&#xff0c;反映还不错。不过前几天&#xff0c;销售部门…

洗衣洗鞋店做小程序有什么优势?

互联网洗衣洗鞋小程序闪亮登场&#xff0c;想知道这款小程序有何魅力吗&#xff1f; 如今&#xff0c;众多商家纷纷推出预约上门洗鞋服务&#xff0c;&#x1f481;‍♀️并倾力打造洗鞋小程序&#xff0c;旨在拓展线上销售渠道。&#x1f31f;那么&#xff0c;这款洗鞋小程序究…

libsndfile读取wav文件基本属性

本文的目的是提供一种方法读取wav文件的基本属性&#xff1a;音频帧数&#xff0c;格式、通道数和采样率信息。 代码如下所示&#xff1a; #include <iostream> #include <QDebug> #include "sndfile.h"using namespace std;int main() {// 初始化 ALS…

Gradio

文章目录 关于 Gradio安装InterfaceChatInterface TextBlocksSentence BuilderDiff Texts MediaSepia FilterVideo IdentityIterative OutputGenerate Tone TabularFilter RecordsVideo IdentityIterative OutputGenerate Tone TabularFilter RecordsTranspose MatrixTax Calcu…

C++ 日志库 log4cpp 编译、压测及其范例代码 [全流程手工实践]

文章目录 一、 log4cpp官网二、下载三、编译1.目录结构如下2.configure 编译3.cmake 编译 四、测试五、压测源码及结果1.运行环境信息2.压测源码3.压测结果 文章内容&#xff1a;包含了对其linux上的完整使用流程&#xff0c;下载、编译、安装、测试用例尝试、以及一份自己写好…

20232906 2023-2024-2 《网络与系统攻防技术》第十次作业

20232906 2023-2024-2 《网络与系统攻防技术》第十次作业 1.实验内容 一、SEED SQL注入攻击与防御实验 我们已经创建了一个Web应用程序&#xff0c;并将其托管在http://www.seedlabsqlinjection.com/&#xff08;仅在SEED Ubuntu中可访问&#xff09;。该Web应用程序是一个简…