Linux
文章平均质量分 82
小黑爱编程
编程小白一枚~
展开
-
【Linux网络】Socket套接字
Socket是一个双向的通信端点。它允许一台计算机的程序与另一台计算机的程序进行数据传输。TCP (传输控制协议):提供可靠的、面向连接的通信服务。TCP连接像一个虚拟的电路,两端通过Socket进行数据传输,确保数据包按顺序到达。UDP (用户数据报协议):提供无连接、尽力而为的通信服务。与TCP不同,UDP没有建立连接过程,数据包可能会丢失或乱序,但它更快,适合对时延敏感的应用场景。原创 2024-09-12 23:18:54 · 764 阅读 · 0 评论 -
【C++】new的底层实现原理
new的底层原理原创 2024-09-11 22:20:55 · 984 阅读 · 0 评论 -
【Linux】可重入与线程安全的联系与区别
虽然可重入函数通常是线程安全的,但线程安全的函数未必是可重入的。例如,某个函数使用了锁来确保线程安全,但它在执行时持有锁,这就意味着它不能在信号处理程序或中断中被安全调用,因此它不是可重入的。的函数是指能够在被中断后,再次从头开始执行而不会影响其正确性的函数。换句话说,如果在一个可重入函数的执行过程中,出现了新的调用(无论是来自同一线程还是另一个线程),函数的执行仍然是正确的。是两个重要概念,它们都与程序在多线程环境下的正确性有关。指的是代码能够在多个线程并发访问的情况下仍能保持正确的行为。原创 2024-09-10 21:06:22 · 1032 阅读 · 0 评论 -
【Linux】线程安全问题
在多线程编程中,线程安全(Thread Safety)是指程序在多个线程同时执行时,能够正确地共享和访问资源而不出现数据不一致或竞争条件的情况。线程安全的代码确保多个线程在没有同步机制的情况下不会破坏数据或引发意外行为。原创 2024-09-10 20:56:46 · 778 阅读 · 0 评论 -
【Linux】 Linux 死锁
死锁指的是多个进程或线程因为互相等待对方持有的资源,导致这些进程或线程都无法继续执行的情况。死锁的典型场景是线程 A 锁住了资源 X,并等待资源 Y,而线程 B 锁住了资源 Y,并等待资源 X。由于双方都在等待对方释放资源,最终进入僵局。原创 2024-09-08 22:17:49 · 1153 阅读 · 0 评论 -
【Linux】Linux 可重入函数
简单来说,可重入函数是线程安全的函数。当函数正在执行时,如果它被其他线程或中断再次调用,它能够正确处理这种情况。不使用静态或全局变量,或仅使用局部变量。不依赖非线程安全的库函数,如malloc或strtok。不修改输入参数。如果函数需要访问共享资源,则必须使用同步机制(如锁或信号量)来避免竞态条件。原创 2024-09-08 22:15:30 · 1063 阅读 · 0 评论 -
【Linux】Linux 共享内存:高效的进程间通信
共享内存是一块可以被多个进程同时访问的内存区域,允许不同进程读取和写入同一份数据。每个进程都可以直接访问这块内存,不需要通过管道、套接字或消息队列进行数据传输。这种直接访问的特点使得共享内存成为最为高效的进程间通信机制之一,适用于需要频繁交换大量数据的场景。原创 2024-09-07 21:01:33 · 1214 阅读 · 0 评论 -
【Linux】Linux 管道:进程间通信的利器
管道是一个双端的通信通道,其中一端用于写数据,另一端用于读数据。它是 Linux 系统中最简单且常用的进程间通信方式之一,尤其适合父子进程之间的数据传递。数据从管道的一端写入,另一端读取,保证了进程之间的同步与协作。原创 2024-09-07 20:59:03 · 691 阅读 · 0 评论 -
【Linux】深入理解Linux文件系统中的inode
inode(Index Node)是Linux文件系统中的一种数据结构,用于存储文件的元数据(metadata),例如文件的大小、权限、所有者、创建时间等。每个文件和目录都对应一个唯一的inode,文件系统通过inode来管理和访问文件的相关信息。需要注意的是,inode不存储文件的实际数据内容,它只包含指向数据块的指针,而数据块中才存储了文件的实际内容。inode在Linux文件系统中扮演着关键角色,负责管理和访问文件的元数据。理解inode。原创 2024-09-04 22:57:23 · 1407 阅读 · 0 评论 -
【Linux】理解Linux中的软链接与硬链接
硬链接是指多个文件名指向同一个数据块。每个硬链接都拥有相同的inode号,即它们实际指向的是相同的物理存储位置。相同的文件数据:硬链接文件与原始文件共享相同的数据块,因此它们的内容完全一致。共享inode号:硬链接与原始文件共享相同的inode号,这意味着它们是同一个文件的不同引用。删除影响:只有当所有硬链接和原始文件都被删除时,数据块才会被释放。如果删除一个硬链接或原始文件,其他硬链接仍然能够访问文件数据。同一文件系统:硬链接只能在同一个文件系统内创建,因为它们直接指向文件的inode。原创 2024-09-04 22:53:09 · 744 阅读 · 0 评论 -
【Linux】理解动态库与静态库:编程中的两种关键库
静态库(Static Library)是指在编译时被嵌入到可执行文件中的库。它通常以.a(在 Unix/Linux 系统中)或.lib(在 Windows 系统中)为扩展名。在程序编译期间,静态库的代码被复制到每一个使用它的可执行文件中,因此,最终生成的可执行文件是一个独立的、完整的二进制文件。动态库(Dynamic Library),也称为共享库(Shared Library),是在程序运行时加载的库。它通常以.so(在 Unix/Linux 系统中)或.dll(在 Windows 系统中)为扩展名。原创 2024-08-30 23:39:37 · 1549 阅读 · 3 评论 -
【Linux】 理解 Linux 中的 `dup2` 函数
dup2dup2是一个强大且灵活的系统调用,可以在文件描述符管理中发挥重要作用。无论是重定向标准输入/输出,还是在进程间通信中创建管道,dup2都是一个不可或缺的工具。通过熟练掌握dup2,你可以更有效地控制程序的 I/O 操作,从而编写出更加健壮和高效的应用程序。原创 2024-08-30 23:35:53 · 1526 阅读 · 0 评论 -
【Linux】深入探讨Linux进程等待:`waitpid`与`wait`
wait是一个用于等待任一子进程终止的系统调用。父进程调用wait后会被挂起,直到它的某个子进程终止,操作系统会将子进程的退出状态返回给父进程。如果没有子进程,wait会立即返回。status:用于存储子进程的终止状态。如果不关心子进程的退出状态,可以将其设置为NULL。正常返回时,wait返回终止的子进程的PID;如果出错,返回-1,并设置errno来指示错误原因。原创 2024-08-29 11:02:39 · 1287 阅读 · 0 评论 -
【Linux】进程等待详解:概念、类型与优化策略
进程等待是指进程在执行过程中因某些条件未满足而暂时停止执行的状态。这些条件可以是等待输入/输出操作完成、资源可用、某个事件发生等。进程等待在多任务操作系统中尤为重要,因为它有助于提高系统资源的利用率。原创 2024-08-29 10:59:08 · 725 阅读 · 0 评论 -
【Linux】exit和_exit的区别
exit()是C标准库中的一个函数,用于正常终止一个进程,并将一个状态码返回给操作系统。它的原型定义在status参数表示进程的退出状态,一般约定0表示成功退出,非零值表示失败或其他状态。exit()调用注册的清理函数在进程的生命周期中,可以通过atexit()函数注册多个清理函数(处理程序),这些函数会在exit()调用时按注册的顺序逆序执行。刷新I/O缓冲区exit()会刷新所有打开的输出流缓冲区,确保所有未写入的数据被写入到对应的文件或终端中。关闭所有打开的文件描述符。原创 2024-08-26 20:22:59 · 996 阅读 · 0 评论 -
【Linux】写时拷贝详解
写时拷贝是一种优化内存资源的技术。其核心思想是:在有多个进程或线程需要共享同一块数据时,操作系统会允许它们共享同一个数据块的副本,而不是为每个进程分配独立的内存空间。只有当其中一个进程尝试修改数据时,系统才会实际进行数据的拷贝,为该进程创建一个独立的副本。这种延迟拷贝的策略大大减少了不必要的内存占用。写时拷贝是一种高效的内存管理技术,通过延迟实际的数据拷贝操作,优化了系统的内存使用和性能。在进程创建、虚拟化以及现代文件系统中,写时拷贝都得到了广泛应用。原创 2024-08-26 20:15:29 · 512 阅读 · 0 评论 -
【Linux】并发与并行:理解多任务处理的核心概念
并发指的是在同一时间段内处理多个任务的能力。并发并不意味着同时执行多个任务,而是指任务之间的切换。操作系统通过时间分片、进程或线程调度等方式,使多个任务看起来像是“同时”进行的。示例:一个简单的例子是你在烹饪时,同时烧水、切菜和炒菜。尽管你不能同时完成所有这些操作,但你可以在烧水的间隙切菜,在切菜的间隙炒菜,最终完成所有任务。并发的关键:并发更关注任务的调度和协调,而非真正的同时执行。即使在单核 CPU 上,也可以通过快速切换任务来实现并发。并行指的是在同一时刻真正地执行多个任务。原创 2024-08-25 16:56:54 · 679 阅读 · 0 评论 -
【Linux】理解操作系统中的进程状态:阻塞、挂起、运行
在现代操作系统中,进程(Process)是一个正在执行的程序实例。为了有效管理进程,操作系统会将每个进程分配到特定的状态。这些状态表示进程当前的活动情况,并帮助操作系统决定如何调度和分配系统资源。创建(New):进程正在创建中。就绪(Ready):进程已准备好运行,等待 CPU 的分配。运行(Running):进程正在占用 CPU 执行指令。阻塞(Blocked):进程正在等待某些事件(如 I/O 操作)完成,无法继续执行。挂起(Suspended):进程被暂时移出内存,停止执行。原创 2024-08-25 16:52:46 · 1081 阅读 · 0 评论 -
【Linux】什么是虚拟内存?
Linux虚拟内存(1)什么是虚拟内存?(2)虚拟内存的工作原理(3)虚拟内存的优点(3)Linux中的虚拟内存管理工具总结虚拟内存是一种内存管理技术,它允许操作系统通过创建一个虚拟的地址空间来模拟比实际物理内存更大的内存容量。操作系统将程序所需的内存分为多个小的内存块(称为页面),并且这些页面可以分布在物理内存和磁盘的交换空间(swap space)中。地址空间的分离:每个进程在虚拟内存中的地址空间是独立的。这意味着一个进程无法直接访问其他进程的内存,这增强了系统的安全性。分页。原创 2024-08-24 16:49:36 · 1378 阅读 · 0 评论 -
【Linux】IP地址和MAC地址
MAC地址是用来识别数据链路层中相连的节点。它的长度为48位比特位,也就是6字节。MAC地址是具有唯一性的,它的唯一性是在网卡硬件生产时就已经制定,所以一个网卡一个MAC地址。这就意味着,一台主机如果有多个网卡,那么就有多个MAC地址。原创 2024-08-23 22:25:39 · 552 阅读 · 0 评论 -
【Linux】在Linux环境下,利用缓冲区实现动画效果的进度条
在linux下,C语言以换行‘\n’为标志刷新缓冲区的数据,也就是我们如果没有‘\n’,我们的信息是先放在缓冲区,然后等代码执行完之后刷新缓冲区的数据,我们才在显示屏上看到打印出来的数据,而我们用fflush可以立即刷新缓冲区。在我们使用printf的时候,我们的数据是先放在缓冲区,然后我们用printf从中拿取,我们可以巧用‘\r’和对缓冲区进行刷新,然后再进行usleep来调整进度条完成的时间,不断打印,来实现动画的效果。第二,我们可以美化一个我们的进度条的效果,给他加上一些颜色,以及一些小框框。原创 2024-08-21 12:54:57 · 348 阅读 · 0 评论 -
【Linux】撕开fork的本质,深入了解fork函数原理
首先,子进程被创建出来之后,会和父进程一起往下执行代码,当一个函数进行到要返回一个值的时候,这个函数它的核心工作肯定是做完了,也就是说,我们的fork函数在返回一个值之前,就已经把我们的子进程给创建好了,实际上fork函数也只有一个返回值。所以我们的return会被我们的父进程返回一次,子进程返回一次,那么就会返回两个值,fork函数的内部肯定是添加了区分开我们父子进程的代码,从而使父进程返回子进程PID,子进程返回0。函数在父进程中返回新创建的子进程的 PID(进程标识符),而在子进程中返回 0。原创 2024-08-20 22:26:04 · 1189 阅读 · 0 评论 -
【Linux网络】带你用生活例子来理解什么是协议
协议就是一种约定,就比如我们生活中我们要发快递,将一个物品交给另一个人,我们在发快递的时候,不仅仅只是将物品给快递员,这样子快递员不知道要将快递发给谁,怎么联系收件人,快递拿到哪里才能交给收件人。而是我们在发快递的时候,会将物品放在快递盒子里打包,然后在快递盒子上添上快递信息,这样就能让我们知道快递是谁发来的,发到哪里,怎么联系对方。原创 2024-08-20 22:24:17 · 831 阅读 · 0 评论 -
【Linux】深入理解进程的优先级(Linux 2.6版本O(1)调度算法)
然后CPU运行活动队列,不需要管新加入的进程,统一将新加入的进程放到过期队列中,过期队列其实就相当于是活动队列的一个镜像,新加入的进程就根据优先级映射到对应的数组下标,然后添加进对应位置的哈希桶里面,当CPU把运行队列里的内容都执行完了。而一个CPU通常一次只能调度一个进程,而操作系统里是有很多的进程需要被调度的,所以这就意味着,这些等待被调度的进程就要进行排队,而排队就要有先后的顺序,也就是进程的优先级,但是这样线性遍历的时间复杂度是一个O(N)级别的,我们操作系统响应是非常快的,这显然不合适。原创 2024-08-16 10:29:56 · 782 阅读 · 0 评论 -
【Linux】什么是进程?
而我们的操作系统肯定不会只是管理一个进程,它肯定要管理很多的进程,那么肯定要有一种特定的数据结构来对进程进行管理,Linux里面,是使用双向链表的形式进行管理,其实就是在task_struct里面添加一个前驱指针和后继指针就可以将它们关联起来。操作系统底层是用C语言编写的,而我们的进程,它会有各种属性,那么各种属性就可以用一个结构体来对进程的各个属性进行描述,然后这个结构体里面,肯定会存在一个指针,指向了我的进程加载在内存对应的代码和数据,一个正在执行的程序,我们称之为进程。然后我们来顺着一条线来思考。原创 2024-08-16 10:28:26 · 378 阅读 · 0 评论 -
【Linux】冯诺依曼体系
所以为了减缓这种速度的差异,就必须要有存储器,有了存储器,我们就可以在CPU还在运行的时候,就提前将数据预加载进内存里存储起来,这样CPU在执行完一个任务之后,就能马上的从内存中将下一个任务拿到,充分的将CPU的资源利用了起来,同样的,我们的输出设备,可能会读取数据比较慢,如果没有内存,CPU就会需要等待输出设备将数据拿走,才能去输入设备拿数据,而内存的存在,CPU只需要将执行完后的结果 “丢进“内存里,它就可以立马去执行下一个任务了,输出设备也只需要从内存中,将数据读取即可。原创 2024-08-16 10:27:32 · 336 阅读 · 0 评论