利用管道通信(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 switchesint main(int argc, char *argv[]) {int pipefd[2][2]; // Array to hold two pipes: one for each direction of communicationchar buf; // Buffer to hold the character read from the pipe// Check if the correct number of arguments are providedif (argc != 3) {fprintf(stderr, "Usage: %s <string> <string>\n", argv[0]);exit(EXIT_FAILURE);}// Create the two pipesif (pipe(pipefd[0]) == -1 || pipe(pipefd[1]) == -1) {perror("pipe");exit(EXIT_FAILURE);}// Fork the process to create a child processint rc1 = fork();if (rc1 < 0) {// Fork failedfprintf(stderr, "fork failed\n");exit(EXIT_FAILURE);} else if (rc1 == 0) { // Child processclose(pipefd[0][0]); // Close unused read end of the first pipeclose(pipefd[1][1]); // Close unused write end of the second pipefor (int i = 0; i < N; ++i) {// Write to the first pipewrite(pipefd[0][1], argv[1], strlen(argv[1]) + 1);// Read from the second pipewhile (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 exitingclose(pipefd[0][1]);close(pipefd[1][0]);exit(EXIT_SUCCESS);} else {// Parent processclose(pipefd[0][1]); // Close unused write end of the first pipeclose(pipefd[1][0]); // Close unused read end of the second pipestruct timeval start, end;// Get the start timeint rc1 = gettimeofday(&start, NULL);for (int i = 0; i < N; ++i) {// Read from the first pipewhile (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 pipewrite(pipefd[1][1], argv[2], strlen(argv[2]) + 1);}// Get the end timeint rc2 = gettimeofday(&end, NULL);assert(rc1 == 0 && rc2 == 0);// Calculate elapsed timedouble elapsed = (double) end.tv_sec + (double) end.tv_usec / 1e6 - ((double) start.tv_sec + (double) start.tv_usec / 1e6);// Calculate average context switch timedouble context_switch = elapsed / (2 * N);printf("Total time: %f seconds\n", elapsed);// Print the average context switch timeprintf("Average context switch time: %lf seconds\n", context_switch);// Close the used pipe endsclose(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.hqwc.cn/news/705472.html

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

相关文章

[Vs2019报错找不到服务实例的解决方案]

计算机疑难杂症记录与分享004 Vs2019报错找不到服务实例的解决方案1、问题现象1.1、问题一&#xff1a;打开vs2019打开项目工程文件&#xff0c;直接弹窗报错1.2、问题二&#xff1a;能打开工程了。识别项目文件不兼容问题。 2、问题原因3、问题一的解决3.1、方法一(亲测无效)3…

Java 自然排序和比较器排序区别?Comparable接口和Comparator比较器区别?

注&#xff1a;如果你对排序不理解&#xff0c;请您耐心看完&#xff0c;你一定会明白的。文章通俗易懂。建议用idea运行一下案例。 1&#xff09;自然排序和比较器排序的区别&#xff1f; 自然排序是对象本身定义的排序规则&#xff0c;由对象实现 Comparable 接口&#xff…

Linux 第三十四章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

基础之音视频2

01 前言 02 mp 03 mp实例 简易音乐播放器 04 音频 sound-pool 1.作用 播放多个音频&#xff0c;短促音频 2.过程 加载load- 3.示例 模拟手机选铃声 步骤&#xff1a; 创建SoundPool对象&#xff0c;设置相关属性 音频流存入hashmap 播放音频 05 videoview 3gp 体积小 mp4 …

掌握Linux常用命令,扫平面试需求障碍

cd 切换目录。 > cd ../ #切换到父级目录 > cd /tmp # 切换到/tmp目录 > cd ~ # 切换到当前用户的家目录 ls命令 查看文件与目录的命令&#xff0c;list 的缩写。 > ls -l #列出长数据串&#xff0c;包含文件的属性与权限数据等 > ls -a #列出隐藏…

Oracle 自治数据库 Select AI 初体验

这几天有点时间&#xff0c;准备尝试下Oracle Select AI&#xff0c;虽然此功能2023年就已经发布了。 Oracle自治数据库已经集成好了Select AI&#xff0c;本文也是讲的这个。 配置 Select AI 需要以下步骤&#xff1a; 创建ADB申请Cohere/OpenAI免费账号设置ADB测试Select…

NSSCTF | [SWPUCTF 2021 新生赛]ez_unserialize

打开题目&#xff0c;发现是一个GIF动图页面&#xff0c;什么都没有。我们来查看一下源代码&#xff0c;看看有没有什么发现 其实只要足够了解网站的构成&#xff0c;看到绿色的注释字样就能知道它这里在提示robots.txt文件。 但是对于小白来说&#xff0c;也不知道它是什么&a…

2、快速搭建Vue框架以及项目工程

本篇文章详细讲解在配置完vue2环境后如何快速搭建一个Vue框架和项目工程。&#xff08;以智慧农业云平台为例&#xff09; 2.1 Vue工程创建 2.1.1创建想要存放的Vue文件夹 找到想要存放的文件夹并在目录搜索框中&#xff0c;并用管理员的方式打开。 2.1.2创建Vue工程 2、安装…

Shopline和Shopify哪个更好?Shopline和Shopify的区别

Shopline和Shopify哪个更好取决于用户面向的市场&#xff0c;面向亚洲市场就更适合有本地化支持的Shopline&#xff0c;而如果希望拓展全球业务&#xff0c;Shopify可能更好。 Shopline和Shopify都是知名的电子商务平台&#xff0c;可以很好的帮助商家搭建和管理在线商店&…

软件测试常见面试题合集(内附详细答案)

01 软件测试理论部分 1.1 测试概念 1. 请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试 单元测试&#xff1a;完成最小的软件设计单元&#xff08;模块&#xff09;的验证工作&#xff0c;目标是确保模块被正确的编码 集成测试&#xff1a;通过测试发现与…

Milvus的存储/计算分离

前言 根据数据面与控制面相隔离的原则&#xff0c;从可扩展性和灾难恢复来看&#xff0c;Milvus由4个相互独立的层组成 访问层 由一系列无状态的代理组成&#xff0c;访问层是系统和用户之间的第一层&#xff0c;它主要是验证客户端请求和规整返回的结果 代理是无状态的&am…

点量云流分享:关于实时渲染云推流技术

提到云串流或者云推流很多人可能和游戏关联起来&#xff0c;其实这个技术的应用领域不仅仅是游戏&#xff0c;还有云上旅游、考古、智慧园区、智慧城市、虚拟仿真等等行业。其解决的问题是将一些大型的3D应用程序放在云端&#xff0c;程序在运行的时候也是在云端&#xff0c;这…