135 Linux 系统编程11 ,linux命令重定向,dup 和dup2,fcntl实现dup ,进程和程序,虚拟内存和物理内存映射关系,pcb进程块详解

一 linux 命令中重定向,使用>实现

通过 大于号  将前面的内容写入到某一个地方

cat main.c > b.txt   //cat main 本身的意思是 显示main.c的值,后面加上 > b.txt 会将显示在屏幕上的字符全部写到b.txt中

例子:将 ls -l 的内容 通过重定向 保存到 list.txt中

hunandede@hunandede-virtual-machine:~$ ls -l > list.txt
hunandede@hunandede-virtual-machine:~$ cat list.txt 
total 80
drwxrwxr-x  2 hunandede hunandede 4096 2月  20 18:55 aaa
drwxrwxr-x  4 hunandede hunandede 4096 2月  21 15:16 day02
drwxrwxr-x 11 hunandede hunandede 4096 2月  23 17:47 day03
drwxrwxr-x  2 hunandede hunandede 4096 2月  28 08:19 day04
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Desktop
drwxr-xr-x  3 hunandede hunandede 4096 1月  23 23:28 Documents
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Downloads
-rw-r--r--  1 hunandede hunandede 8980 1月  23 20:24 examples.desktop
drwxrwxr-x  2 hunandede hunandede 4096 2月  20 17:39 head
-rw-rw-r--  1 hunandede hunandede    0 2月  28 08:23 list.txt
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Music
drwxrwxr-x  2 hunandede hunandede 4096 1月  23 23:47 mydocument
drwxrwxr-x  3 hunandede hunandede 4096 2月  19 14:05 nginx
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Pictures
drwxrwxr-x  3 hunandede hunandede 4096 2月  23 00:40 projects
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Public
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Templates
drwxr-xr-x  2 hunandede hunandede 4096 1月  23 21:50 Videos
drwxr-xr-x  3 hunandede hunandede 4096 1月  23 21:04 下载

二 dup 和dup2 函数 重点是dup2函数的理解和应用

重定向对象的函数就是 dup 和dup2

dup 函数 非重点

函数原型

       #include <unistd.h>

       int dup(int oldfd);
       
 

函数意思

The  dup()  system  call  creates  a copy of the file descriptor oldfd,

dup函数主要是将 参数fd 拷贝一份,有就是让 多个fd 指向同一个文件

返回值:

成功,返回可以使用的新的值

失败,返回-1,errno被设置

RETURN VALUE
       On success, these system calls return the new descriptor.  On error, -1
       is returned, and errno is set appropriately.
 

dup2 函数 重点

函数原型

       #include <unistd.h>

int dup2(int oldfd, int newfd);

函数参数

oldfd 

newfd

函数意义:

使用oldfd 的值 替换 newfd的值

也就是说newfd也会指向oldfd的内容

返回值

成功的话,返回newfd 的值,失败返回-1,errno 被设置。

例子验证:

dup例子

//dup例子

int main(int argc , char * argv[]) {
	int  ret = 0;
	//int fd = open(argv[1], O_RDWR);
	int fd = open("/home/hunandede/projects/linuxcpp/main.cpp", O_RDWR);
	//int fd = open("/home/hunandede/projects/linuxcpp/dict.txt", O_RDWR);
	if(fd == -1)
	{
		perror("open file fail \n");
		ret = fd;
		return ret;
	}
	int fd2 = dup(fd);
	if (fd2==-1) {
		perror("dup fd error");
		ret = fd2;
		return ret;
	}
	printf("fd = %d,fd2 = %d\n",fd,fd2);

	//那么这里可以通过fd2读取fd中的数据吗?测试一下
	//测试中,我们发现,第一个bufread 前三个字符是 -17 -69 -65, 这是UTF-8格式的前三位,
	char bufread[10] = { 0 };
	ret = read(fd2,bufread,10);

	if (ret<0) {
		perror("read fd2 error\n");
		return ret;
	}
	else {
		cout << bufread << endl;
	}

	bufread[10] = { 0 };
	ret = read(fd2, bufread, 10);

	if (ret < 0) {
		perror("read fd2 error\n");
		return ret;
	}
	else {
		cout << bufread << endl;
	}

	//前面使用fd2都是可以读取到的,且第二次读取会紧挨着第一次读取到的位置
	//那么我们接着从fd读,是否可以呢?结果是可以的,那么我们要close 的时候,要close几次呢?

	bufread[10] = { 0 };
	ret = read(fd, bufread, 10);

	if (ret < 0) {
		perror("read fd error\n");
		return ret;
	}
	else {
		cout << bufread << endl;
	}

	ret= close(fd);
	cout << "start close rer " << ret<<  endl;
	ret = close(fd2);
	cout << "end close ret " << ret <<endl;
	return 0;
}

dup2例子

//dup2例子,注意两个问题:
//1.open几个file,就要close几个file
//2.如果使用不同的fd,对同一个文件,进行读写,那么读取的位置不会发生变化,每次都在上一次读取的位置停留

int main() {

	int ret = 0;
	int fd = open("/home/hunandede/projects/linuxcpp/main.cpp", O_RDWR);
	int fd2 = open("/home/hunandede/projects/linuxcpp/dict.txt", O_RDWR);
	cout << fd << "  " << fd2 << endl;
	ret = dup2(fd,fd2);//fd中的内容替换了fd2中的内容,fd还是3,fd2还是4,不过是fd2指向的已经变成fd的指向了
	
	cout << "after " << fd << "  " << fd2 << endl;
	char readbuf[10] = { 0 };
	read(fd2,readbuf,10);
	cout << readbuf << endl;

	readbuf[10] = { 0 };
	read(fd2, readbuf, 10);
	cout << readbuf << endl;

	readbuf[10] = { 0 };
	read(fd, readbuf, 10);
	cout << readbuf << endl;

	ret = close(fd);
	cout << "ret = " << ret << endl;
	ret = close(fd2);
	cout << "retaaa = " << ret << endl;


	return 0;
}

三 fcntl实现dup 和 dup2 知道就行

//fcntl实现dup, 知道有这种写法就行
int main() {
	cout << "start " << endl;
	int fd = open("/home/hunandede/projects/linuxcpp/main.cpp", O_RDWR);
	int fd2 = fcntl(fd,F_DUPFD,0);
cout << fd << "  " << fd2 << endl;    //最后一个参数,表示我们想要的fd的值,但是结果为 3 和 4,这是因为0,已经被占用,系统默认给一个可以使用的空闲的fd。

	int fd3 = fcntl(fd,F_DUPFD,7);//结果为7 这是因为7没有被使用
	char readbuf[10] = { 0 };
	read(fd2, readbuf, 10);
	cout << readbuf << endl;

	readbuf[10] = { 0 };
	read(fd2, readbuf, 10);
	cout << readbuf << endl;


	readbuf[10] = { 0 };
	read(fd, readbuf, 10);
	cout << readbuf << endl;

	int ret = close(fd);
	cout << "ret = " << ret << endl;

	ret = close(fd2);//clost 这个也不会error,成功关闭。
	cout << "retaaa = " << ret << endl;
	return 0;
}

四,进程和程序,

程序和进程

程序,是指编译好的二进制文件,在磁盘上存放

           不占用系统资源(cpu、内存、打开的文件、设备、锁....)

进程,是一个抽象的概念,与操作系统原理联系紧密。进程是活跃的程序,占用系统资源。在内存中执行。(程序运行起来,产生一个进程)

程序 → 剧本(纸) 进程 → 戏(舞台、演员、灯光、道具...)

同一个剧本可以在多个舞台同时上演。同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)

如:同时开两个终端。各自都有一个bash但彼此ID不同。

五 多道程序设计: 了解

我们会一边看小说,一边听歌,这说明计算机 在 同时的进行两个不同的进程,一个QQ小说,一个千千静听

那么计算机是怎么做到的呢?

在单核CPU 的年代,是通过

它们在管理程序控制之下,相互穿插的运行。多道程序设计必须有硬件基础作为保证。

时钟中断即为多道程序设计模型的理论基础。 并发时,任意进程在执行期间都不希望放弃cpu。因此系统需要一种强制让进程让出cpu资源的手段。时钟中断有硬件基础作为保障,对进程而言不可抗拒。 操作系统中的中断处理函数,来负责调度程序执行。

在多道程序设计模型中,多个进程轮流使用CPU (分时复用CPU资源)。而当下常见CPU为纳秒级,1秒可以执行大约10亿条指令。由于人眼的反应速度是毫秒级,所以看似同时在运行。

1s = 1000ms, 1ms = 1000us, 1us = 1000ns    1000000000

实质上,并发是宏观并行,微观串行!

六 虚拟内存和物理内存映射关系

cpu执行代码的大致逻辑如下

我们在这里是要知道这个 MMU,MMU存在于CPU 的内部,是一个计算机的硬件,

主要功能是:

虚拟地址到物理地址的转换(即虚拟内存管理)、 我们在这里,主要了解这个功能

内存保护、

中央处理器高速缓存的控制

那么这个物理内存和虚拟内存分别指的是什么?他们又是怎么映射的呢?

当每一个程序跑起来的时候,就会给这个程序一个虚拟的内存,如下图左边的部分,

物理内存就是我们买电脑时配置的那块内存,当前假设是512M的金士顿的内存条

物理内存和虚拟内存通过MMU 这个中间翻译官进行映射

好,我们把上图再完善一下,当同时有两个进程 a.out  和 b.out 跑起来的情况

最终图:

也就是,因为不同的进程的kernel中的元素 通过 MMU 最后 映射的物理内存是在 同一片 区域的,因此才有后面学习的进程间通讯的内容,不然怎么通讯呢?

七 pcb进程块详解
 

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

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

相关文章

基于springboot实现二次元商品购物系统项目【项目源码+论文说明】

基于springboot实现二次元商品购物系统演示 摘要 时代的变化速度实在超出人类的所料&#xff0c;21世纪&#xff0c;计算机已经发展到各行各业&#xff0c;各个地区&#xff0c;它的载体媒介-计算机&#xff0c;大众称之为的电脑&#xff0c;是一种特高速的科学仪器&#xff0…

RV32/64 特权架构 - 特权模式与指令

RV32/64 特权架构 - 特权模式与指令 1 特权模式2 特权指令2.1 mret&#xff08;从机器模式返回到先前的模式&#xff09;2.2 sret&#xff08;从监管模式返回到先前的模式&#xff09;2.3 wfi&#xff08;等待中断&#xff09;2.4 sfence.vma&#xff08;内存屏障&#xff09; …

什么是负载均衡集群?

目录 1、集群是什么&#xff1f; 2、负载均衡集群技术 3、负载均衡集群技术的实现 4、实现效果如图 5、负载均衡分类 6、四层负载均衡&#xff08;基于IP端口的负载均衡&#xff09; 7、七层的负载均衡&#xff08;基于虚拟的URL或主机IP的负载均衡) 8、四层负载与七层…

C语言————结构体

接下来我们来了解C语言中很重要的内容&#xff1a;结构体。虽然到现在我们可以创建常量&#xff0c;变量&#xff0c;数组&#xff0c;但是存储的都是相同类型的数据&#xff0c;如果我们需要写入不同数据类型的信息怎么办&#xff0c;例如常见的身份证上的信息&#xff0c;有身…

进程间通信,无名管道pipe,有名管道mkfifo,信号的基础概念,signal函数

我要成为嵌入式高手之2月28日Linux高编第十一天&#xff01;&#xff01; 学习笔记 进程间通信 总共6种通信方法&#xff0c;主要是前五种方式 第一种方式&#xff1a;管道 一、无名管道 只能用于具有亲缘关系的进程间通信 pipe #include <unistd.h> int pipe(i…

ETH开源PPO算法学习

前言 项目地址&#xff1a;https://github.com/leggedrobotics/rsl_rl 项目简介&#xff1a;快速简单的强化学习算法实现&#xff0c;设计为完全在 GPU 上运行。这段代码是 NVIDIA Isaac GYM 提供的 rl-pytorch 的进化版。 下载源码&#xff0c;查看目录&#xff0c;整个项目…

2024年3月5-7日第12届生物发酵技术装备展-奥博仪表

参观企业介绍 潍坊奥博仪表科技发展有限公司成立于2002年3月&#xff0c;注册资金1000万元&#xff0c;已有20多年的发展历程&#xff0c;是一家专业从事流量仪表开发、生产与测控系统集成的高新技术企业和双软认证企业。 目前公司以仪表、通讯产品、自控系统、软件的研发、生…

DVWA 靶场之 Command Injection(命令执行)middlehigh

对于 middle 难度的 我们直接先看源码 <?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ];// Set blacklist$substitutions array(&& > ,; > ,);// Remove any of the characters in the array (blacklist).$target str_rep…

Pytest教程:一种利用 Python Pytest Hook 机制的软件自动化测试网络数据抓包方法

随着计算机技术的发展&#xff0c;使得网络应用的数量不断增加&#xff0c;因此网络数据抓包成为了网络应用开发和测试中非常重要的一部分。目前&#xff0c;已有许多网络数据抓包工具可供使用&#xff0c;例如 Wireshark、Tcpdump、Fiddler 等&#xff0c;但这些工具需要手动配…

5G网络频谱划分与应用

频率越大&#xff0c;波长越短。补充&#xff1a;微波频段&#xff1a;300MHZ~3000GHZ。 5G网络工作频带与带宽配置 &#xff08;1&#xff09; FR1:410MHZ~7125MHZ。 FR2&#xff1a;24250MHZ~52600MHZ 注&#xff1a;早期将6GHZ已下频段作为FR1&#xff0c;但是最新的频段…

Python打发无聊时光:10.用flask创造按键控制的网页小游戏

游戏介绍: 《秦蓝大冒险》是一款简单而紧张的追逐游戏。在这个游戏中&#xff0c;玩家将控制一名名叫“吕千”的角色&#xff0c;试图在一个封闭的空间内逃避一个名为“秦蓝”的追逐者。随着时间的推移&#xff0c;“秦蓝”会不断追踪玩家的位置&#xff0c;努力捕捉到他。 游…

C语言中如何进行内存管理

主页&#xff1a;17_Kevin-CSDN博客 收录专栏&#xff1a;《C语言》 C语言是一种强大而灵活的编程语言&#xff0c;但与其他高级语言不同&#xff0c;它要求程序员自己负责内存的管理。正确的内存管理对于程序的性能和稳定性至关重要。 一、引言 C 语言是一门广泛使用的编程语…

2.1_6 线程的实现方式和多线程模型

文章目录 2.1_6 线程的实现方式和多线程模型&#xff08;一&#xff09;线程的实现方式&#xff08;1&#xff09;用户级线程&#xff08;2&#xff09;内核级线程 &#xff08;二&#xff09;多线程模型&#xff08;1&#xff09;一对一模型&#xff08;2&#xff09;多对一模…

stable diffusion webUI之赛博菩萨【秋葉】——工具包新手安裝与使用教程

stable diffusion webUI之赛博菩萨【秋葉】——工具包新手安裝与使用教程 AI浪潮袭来&#xff0c;还是学习学习为妙赛博菩萨【秋葉】简介——&#xff08;葉ye&#xff0c;四声&#xff0c;同叶&#xff09;A绘世启动器.exe&#xff08;sd-webui-aki-v4.6.x&#xff09;工具包安…

VirtualBox虚拟机配置双网卡

安装完后Linux后。下一步需要设置Linux的网络。为了便于学习测试&#xff0c;通常我们需要虚拟机能通宿主机和外网。类似达到下面的效果。虚拟机跟宿主本机和外网&#xff0c;及另外一台同网段的虚拟机也是相通 解决思路是-->配置双网卡&#xff0c;网卡1使用NAT网络模式&a…

vue组件中data为什么必须是一个函数

查看本专栏目录 关于作者 还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#x…

fiddler抓包工具使用(一)

一、fiddler简介 1. 简介 fiddler是一款强大的抓包工具&#xff0c;它的原理以web代理服务器的形式进行工作fiddler是好用的web调试工具之一 能记录所有客户端和服务器的http和https请求修改输入、输出数据包数据允许监视设置断点弱网测试 2. 工作原理 代理就是在客户端和服…

QT C++实战:实现用户登录页面及多个界面跳转

主要思路 一个登录界面&#xff0c;以管理员Or普通用户登录管理员&#xff1a;一个管理员的操作界面&#xff0c;可以把数据录入到数据库中。有返回登陆按钮&#xff0c;可以选择重新登陆&#xff08;管理员Or普通用户普通用户&#xff1a;一个主界面&#xff0c;负责展示视频…

java动态代理面试题,java反射原理面试题

01 并发宝典&#xff1a;面试专题 面试专题分为四个部分&#xff0c;分别如下 Synchronized 相关问题 可重入锁 ReentrantLock 及其他显式锁相关问题 Java 线程池相关问题 Java 内存模型相关问题 1.1 Synchronized 相关问题&#xff08;这里整理了八问&#xff09; 问题一…

揭示预处理中的秘密!(二)

目录 ​编辑 1. #运算符 2. ##运算符 3. 命名约定 4. #undef 5. 命令行定义 6. 条件编译 7. 头文件的被包含的方式 8.嵌套文件包含 9. 其他预处理指令 10. 完结散花 悟已往之不谏&#xff0c;知来者犹可追 …