linux
最新文章【linux】进程间如何实现通信
概述
什么是通信
进程通信是指不同进程之间在操作系统环境下交换数据、共享信息或者进行协作的过程。多个进程间可能需要相互协作来完成复杂的任务。
其本质可以简单的理解为让多个进程看到同一份"资源"。
这个资源一般指的是特定形式的内存空间,其属于操作系统管辖。这个资源不属于任一个进程,否则这会破坏进程的独立性。访问资源也就等同于访问操作系统。所以在通信过程中不过避免的会使用到系统调用接口。
数进程通信允许进程之间传递数据,可以是简单的消息、文件、共享内存或者其他形式的信息,也涉及到进程之间的同步,确保它们按照预期的顺序执行,并协同工作以完成特定的任务。
通信目的
其目的可以总结为三点:
资源共享: 允许进程共享信息和资源,如文件、内存等,以便彼此访问和使用这些资源。
协同工作: 多个进程可能需要合作完成一个大型任务,进程通信允许它们之间进行有效的协调和合作。
并发控制: 控制并发进程的访问,确保数据的一致性和完整性,避免竞态条件和数据损坏。
通信方式
管道
匿名管道pipe
命名管道
System V IPC
System V 消息队列
System V ...
linux
【linux】如何加载进程
前言:在之前的博客介绍了进程地址空间,提到了地址空间是如何与物理内存相映射以及一些简单的运行机制,但在物理内存下,还存在与磁盘的交互,在磁盘中一个程序代码是如何存储的?又是怎么一步步加载到内存中?是谁在调度这一切?
虚拟地址与物理地址
虚拟地址是指计算机中程序所使用的地址空间,它是在程序执行过程中由程序产生的地址。在虚拟内存系统中,每个程序都有自己的虚拟地址空间,这使得每个程序都认为它是在独占地使用整个计算机内存。虚拟地址由操作系统和硬件共同管理,而程序中使用的地址都是虚拟地址。在程序执行时,虚拟地址会被映射到物理地址上。
物理地址是计算机内存中实际存储数据的地方。它是计算机内存芯片上的唯一标识位置,是硬件直接访问的地址。物理地址空间是实际存在于计算机硬件上的内存空间。操作系统通过使用内存管理单元(MMU)将虚拟地址映射到物理地址,从而实现虚拟内存的概念。
假设一个程序要访问地址0x00400000,这就是它的虚拟地址。在虚拟内存系统中,这个地址会被映射到计算机内存的另一个位置,比如物理地址0x0000A000。当程序试图访问虚拟地址0x00400000时,操作系统会通过MMU将它 ...
linux
【linux】关于文件,你可能需要知道这些
回顾c语言的文件操作
相关接口
简单的回顾下在c语言中,我们是如何使用相关的文件接口的。
C语言提供了一套强大而灵活的文件接口,使得程序能够在磁盘上读取和写入数据。这个文件接口是操作系统提供的API(应用程序编程接口)的一部分,这里则是简单介绍一下C语言中常用的文件接口,包括文件的打开、读取、写入、关闭等操作。
打开文件
在C语言中,要对一个文件进行操作,首先需要将其打开。这可以通过使用fopen函数来实现。
12FILE *fptr; // 声明一个文件指针fptr = fopen("example.txt", "r"); // 打开名为example.txt的文件以供读取
声明了一个文件指针fptr,使用fopen函数将名为example.txt的文件以只读模式打开,函数返回一个指向该文件的指针。
读取文件
一旦文件打开成功,我们可以使用fread函数来读取文件内容。
12char buffer[100]; // 声明一个用于存储数据的缓冲区fread(buffer, sizeof(char), 100, fptr); // ...
linux
【linux】简单模拟shell的实现
什么是Shell
在Linux系统中,Shell是一种命令行界面,用于与Linux操作系统进行交互和控制。它是用户与操作系统内核通信的接口,允许用户输入命令,然后操作系统执行这些命令。Shell也可以执行脚本,这些脚本是一系列命令的集合,可以自动化执行多个任务。
常见的Linux Shell包括:Bash(Bourne Again Shell),Zsh,Fish,Dash和Ksh(Korn Shell)。
其中最为常用的就是Bash。
不同的Shell提供不同的功能和语法,用户可以根据自己的需求和偏好选择适合的Shell。无论使用哪种Shell,它们都允许用户执行文件操作、管理进程、配置系统和执行各种系统任务。
接下来就是一个简单实现shell的代码。
Shell的实现
参照普通的linux命令行:
先来给出一个类似的格式:
123456789101112131415161718192021222324#define LEFT "[" // 左括号#define RIGHT "]" // 右括号#define LABLE "#&quo ...
linux
【linux】初识进程地址空间
引入
先来看一段代码:
12345678910111213141516171819202122232425262728int main(){ pid_t id = fork(); //调用fork函数使父子进程依次启动。 if(id == 0) { int cnt = 5; // 子进程 while(1) { printf("i am child, pid : %d, ppid : %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val); sleep(1); if(cnt) cnt--; else { g_val=200; printf("child g_val : 100->200\n"); ...
c/c++
【c++】左值与右值
☀️什么是左值?什么是右值?
左值(L-value)是可以标识内存位置的表达式,通常是变量或者对象的名称。右值(R-value)是指表达式的值,但不能标识内存位置。在Cpp中,左值可以出现在赋值语句的左边,而右值则通常出现在赋值语句的右边。
常见左值:变量名或解引用的指针
常见右值:字面常量、表达式返回值
简单的举几个例子:
12345678910int x = 5; // 'x' 是左值,因为它标识了内存位置int y = x; // 'x' 在赋值语句的右边,是右值int* ptr = &x; // 'ptr' 是左值,因为它存储了 'x' 的地址int z = *ptr; // '*ptr' 是右值,因为它是 'ptr' 指向的内存位置的值int getResult() { return 42;}int result = getResult(); // 'getResult()' 是右值,因为 ...
数据结构与算法
【算法】汉诺塔
这篇博客是很早在csdn上写的,最近碰到汉诺塔的问题又有些不太清楚,就搬运过来了。
【游戏规则】(摘自百度百科):汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
在书写汉诺塔的代码前需要掌握其主要的移动思路。
以3层的汉诺塔为例(代码为java):
解决汉诺塔的核心思路是:A柱和C柱必须畅通无阻,也就是1,2必须堆叠在B柱上,只留最下面的3,此时就可以将3从A柱移动至C柱。
解决汉诺塔就是将核心思路不断拆分实现。
第一步:
将A柱上的n-1个圆盘移到B柱上。
将A柱上的第n个也就是最后一个圆盘移到C柱上。
第二步:
将B柱上的n-1个圆盘移到C柱上。
先假定一个函数,取名为hanoi。
1public void hanoi (int n,String a,String b,String c)
其四个参数 ...
数据结构与算法
【数据结构】哈希表的实现
引入
查找是编程里无法绕开的一环,在顺序结构或者树结构中,由于不存在某种元素与位置的映射关系,所以顺序查找时间复杂度为O(N),平衡树中为树的高度,即O($log_2 N$),搜索的效率取决于搜索过程中元素的比较次数。
那么一种较为理想的查找就是可以不经过任何比较,一次直接从表中得到要搜索的元素。
如果构造一种存储结构,通过某种函数(hashFunc)使得元素的存储位置与它的关键码之间能够建立一一映射的关系,那么在查找时通过该函数可以很快找到该元素。
哈希表(Hash Table)是一种常见的数据结构,主要用于存储键值对。它通过将键映射到一个固定长度的数组中来实现快速访问和查找。
哈希表由一个固定长度的数组和一组哈希函数组成。当插入一个键值对时,哈希函数会将键映射到数组的一个位置上,然后将该键值对存储在该位置上。当需要查找一个键对应的值时,哈希函数可以快速地将键映射到数组的位置,并返回存储在该位置上的值。这也是哈希表工作的基本原理。
然而,由于哈希函数的映射过程是将一个无限的键空间映射到一个有限的数组空间中,所以不可避免地会出现哈希冲突。哈希冲突指的是两个不同的键被映射到了数组的同 ...
数据结构与算法
【数据结构】map与set,基于红黑树的简单模拟实现
阅读本文前最好了解AVL树的相关简单实现。
map与set
map是一种关联数组(Associative Array),也被称为字典(Dictionary)或键值对(Key-Value)容器。它将键和值一一对应存储,通过键快速查找对应的值。在map中,键是唯一的,且按照一定的排序规则进行存储。
简单的代码示例(使用map存储学生姓名与分数):
12345678910111213141516171819#include <iostream>#include <map>int main() { std::map<std::string, int> studentScores; // 添加学生姓名和分数 studentScores["Alice"] = 95; studentScores["Bob"] = 80; studentScores["Charlie"] = 90; // 遍历map,输出学生姓名和分数 for (const auto ...
数据结构与算法
【数据结构】AVL树的插入与旋转
🏠引入
AVL树是一种自平衡的二叉搜索树,它可以在插入和删除操作之后自动调整树的结构,以保持树的平衡性。AVL树是由计算机科学家Adelson-Velsky和Landis于1962年提出的,它的名称来源于他们的姓氏的首字母。
AVL树是平衡的搜索二叉树。
在AVL树中,每个节点都有一个平衡因子,用来衡量左子树和右子树的高度差。平衡因子可以是-1、0或1,如果平衡因子超过这个范围,就表示树不平衡了。为了保持树的平衡性,AVL树使用旋转操作来调整树的结构。
下面是一个简单的AVL树的图例:
123456789 11 / \ 7 16 / \ \3 9 26 \ / 10 18
这个AVL树是平衡的,因为每个节点的左右子树的高度差不超过1。
平衡因子一般是右子树高度减去左子树高度。其取值只能是-1,0,1三个中的一个。
🏡代码示例
🏢AVLTree类
12345678910111213141516171819202122232425262728293031323334#pragma once#include ...