
Linux系统编程
文章平均质量分 66
alpha_2017
这个作者很懒,什么都没留下…
展开
-
linux 进程的pid分配策略——pid位图算法
https://www.bilibili.com/video/BV1aK4y1C7DH?from=search&seid=13205632413617942586转载 2021-09-23 22:53:24 · 1533 阅读 · 0 评论 -
Linux系统编程 -- 多线程之基于环形队列的生产者与消费者模型
(1)什么是信号量前面的叙述中,我们通过锁保证了每次只有一个线程进入临界区,但是临界区资源很多也很大,每次只允许一个线程进入往往会使效率很低。所以如果将临界区划分为多个独立的区域,划分为多少个区域就让多少个线程进入,,但是这样就同时带来了一个问题——如果划分为了5个区域,但是同时进入了10个线程该怎么办?所以这一点可以通过信号量解决。信号量可以理解为一个计数器,它用来描述临界资源的有效个数信号量由一个值和一个指针组成,指针指向等待该信号量的线程。信号量的值表示相应资源的使用情况,比如如果S>=0表转载 2021-05-05 22:38:48 · 271 阅读 · 0 评论 -
Linux系统编程 -- 多线程之基于阻塞队列生产者与消费者模型
(1)生产者与消费者模型概述在现实生活中,当我们缺少某些生活用品时,就回到超市去购买。当你到超市时,你的身份就是消费者,那么这些商品又是哪里来的呢,自然是供应商,那么它们就是生产者,而超市在生产者与消费者之间,就充当了一个交易场所。正是这样的方式才使得人类的交易变得高效,生产者只需要向超市供应商品,消费者只需要去超市购买商品计算机是现实世界的抽象,因此像这种人类世界的模型,自然也被引入到了计算机当中。在实际软件开发中,进程或线程就是生产者和消费者,他们分别产生大量数据或消耗大量数据,但是他们之间一般不直转载 2021-05-05 22:36:09 · 238 阅读 · 0 评论 -
Linux系统编程 -- 死锁
死锁A:死锁的概念当两个线程同时拥有一定的资源,但是都缺少对方手上的资源才能进行下一步动作,而去竞争对方的资源,从而都陷入等待的一种场景,这种场景被称为死锁。例如:A、B线程在运行开始时分别持有a、b对象,A拥有a,对象a被A上锁了,B拥有b,对象b被B上锁了,此时,线程A在要往后运行需要对象b,而线程B要往后运行需要对象a,此时A、B线程都希望获得对方的资源,但是手上的资源都不愿拿出来,这个时候就形成了“僵局”,进入了死锁B:死锁的四个必要条件产生死锁必定要满足以下条件互斥条件:一个资源每次只能原创 2021-05-05 22:09:46 · 199 阅读 · 0 评论 -
Linux系统编程 -- IO缓冲区
标准I/O库提供缓冲的目的是尽可能地减少使用read和write调用的次数。它也对每个I/O流自动地进行缓冲管理,从而避免了应用程序需要考虑这一点所带来的麻烦。不幸的是,标准I/O库最令人迷惑的也是它的缓冲。标准I/O提供了三种类型的缓冲:1、全缓冲:在填满标准I/O缓冲区后才进行实际I/O操作。常规文件(如普通文本文件)通常是全缓冲的。2、行缓冲:当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。这允许我们一次输出一个字符,但只有在写了一行之后才进行实际I/O操作。标准输入和标准输出对原创 2021-05-04 21:01:15 · 206 阅读 · 0 评论 -
Linux系统编程 -- volatile关键字
volatile关键字修饰的变量,在程序执行的时候,不会从寄存器中读取,而是从内存中读取。在编译的时候编译器开启了优化,在使用volatile 关键字修饰后,就不会被优化。举例:#include <stdio.h>#include <signal.h>volatile int flag=0;void handler(int sig){ flag=1; printf("flag被设置为了1\n");}int main(){ signal(2,handler原创 2021-05-04 20:46:32 · 126 阅读 · 0 评论 -
Linux系统编程 -- 进程 信号
/***********************************************************************信号产生1.coredump产生信号2.kill3.raise4.abort5.由软件定时器产生 SIGALRM6. 硬件异常产生************************************************************************///1.coredump产生信号#include<stdio.h原创 2021-05-04 14:04:24 · 170 阅读 · 0 评论 -
Linux系统编程 -- 信号及signal函数
信号分类:进程可以捕捉到信号,并根据这些信号做出回应1.信号分为下面这些:2. 进程捕捉到信号有三种处理方式:忽略此信号 SIGIGN执行该信号的默认动作SIG_DFL提供一个信号处理函数,要求内核在处理该信号时,切换到用户态执行整个函数模拟2号信号ctrl +c 信号,只能发送给前台进程,一个命令后面加入&会进入后台执行shell可以同时运行一个前台进程和多个后台进程,但是只有前台进程能够捕捉到整个信号前台进程在执行过程中接收这个信号,也就是说用户进程的用户代码运行到任何原创 2021-05-04 13:08:14 · 323 阅读 · 0 评论 -
Linux系统编程 -- stdin stdout stderr
标准输入 标准输出 标准错误#include<stdio.h>#include<string.h>/* #include <stdio.h> FILE *fopen(const char *pathname, const char *mode); FILE *fdopen(int fd, const char *mode); FILE *freopen(const char *pathname, const char *mode.原创 2021-05-04 12:41:17 · 230 阅读 · 0 评论 -
Linux系统编程 -- exec函数族
进程替换?父子进程之间是共享代码的,那么如果希望子进程去执行其它函数,而不是父进程的代码完成这样的操作:需要使用到exec函数族,去执行另外一个程序,进程调用exec函数时,进程的用户空间代码和数据会完全被新的程序代替,这并没有去创建新的进程,而是代码段和数据段的替换2.函数如下:int execl(const char *path, const char *arg, ...);int execlp(const char *file, const char *arg, ...);int..原创 2021-05-04 01:55:54 · 374 阅读 · 1 评论 -
Linux系统编程 -- 进程控制 进程终止
进程终止:进程正常执行完成后退出进程异常退出系统调用主动退出进程// 1 进程正常退出#include<stdio.h>int main(void){ printf("hello world\n"); return 0;}// 2. 进程异常退出#include<stdio.h>int main(){ int a = 100/0; return 0;}// 3. 进程主动终止,会刷新缓冲区#include<st原创 2021-05-04 00:56:59 · 141 阅读 · 0 评论 -
工程管理 -- makefile
编译appSTALIB=../staticlibDYNAMICLIB=../dynamic######### 标准Makefile Lv1 ######## EXTENSION=cCC=gccLIB=libstatic_test.aSUBDIR=./sourceOBJ = objDEP = depTARGET = app#CXXFLAGS:编译选项, LDFLAGS:链接选项 CXXFLAGS +=-I./include \ -I../staticlib/include\ -原创 2021-02-21 11:46:24 · 149 阅读 · 0 评论 -
linux 文件锁
1. 文件锁基本概念Linux中软件、硬件资源都是文件(一切皆文件),文件在多用户环境中是可共享的。文件锁是用于解决资源的共享使用的一种机制:当多个用户需要共享一个文件时,Linux通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。文件锁包括建议性锁和强制性锁:建议性锁:要求每个使用上锁文件的进程都要检查是否有锁存在,并且尊重已有的锁。在一般情况下,内核和系统都不使用建议性锁,它们依靠程序员遵守这个规定。强制性锁:是由内核执行的锁,当一个文件被上锁进行写入操作的时候,内核将阻止其他任何原创 2021-02-17 21:40:40 · 2213 阅读 · 0 评论 -
linux -- open /acess/ftruncate/lstat 函数
头文件:#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>定义函数: int open(const char * pathname, int flags); int open(const char * pathname, int flags, mode_t mode);函数说明:参数 pathname 指向欲打开的文件路径字符串. 下列是参数flags 所能使用原创 2021-02-17 21:08:36 · 232 阅读 · 0 评论 -
管道 mkfifio函数的使用
mkfifo命令生成管道文件mkfifo函数 第一参数路径, 第二是权限int mkfifo(const char *pathname, mode_t mode);写入数据#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#incl.原创 2021-02-17 20:48:57 · 441 阅读 · 0 评论 -
Linux系统编程—— fork() 函数详解
需要的头文件:#include <sys/types.h>#include <unistd.h>pid_t fork(void);功能:用于从一个已存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。参数:无返回值:成功:子进程中返回 0,父进程中返回子进程 ID。pid_t,为无符号整型。失败:返回 -1。失败的两个主要原因是:1)当前的进程数已经达到了系统规定的上限,这时 errno 的值被设置为 EAGAIN。2)系统内存不足,这时 err转载 2021-02-10 11:57:54 · 612 阅读 · 0 评论 -
container_of(ptr, type, member)宏定义解析
简单应用 - 图形解析:codetest.c#include <unistd.h>#include <stdio.h>#include <stdarg.h>#include <string.h>#include <stdlib.h>/*container_of()这个宏定义的功能是根据一个已知结构体成员的指针和变量名得出宿主结构体的地址为方便理解和描述,本文中将已知的结构体成员叫做功能成员,它所在的结构体叫做宿主结构体原创 2020-10-16 23:02:50 · 771 阅读 · 0 评论 -
缺页中断——FIFO、LRU、OPT这三种置换算法
1. 缺页中断 在请求分页系统中,可以通过查询页表中的状态位来确定所要访问的页面是否存在于内存中。每当所要访问的页面不在内存时,会产生一次缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。 缺页本身是一种中断,与一般的中断一样,需要经过4个处理步骤: 1. 保护CPU现场 2. 分析中断原因 3. 转入缺页中断处理程序进行处转载 2017-09-12 22:31:12 · 4619 阅读 · 0 评论 -
linux系统编程 -- 编程入门
argc是命令行总的参数个数argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数,比如:#include<stdio.h>#include<stdlib.h>int main(int argc,char *argv[]){ for(int i=0;i<argc;i++){ ...原创 2017-03-15 12:58:40 · 299 阅读 · 0 评论 -
makefile ------ subst、foreach、wildcard、notdir
subst、foreach、wildcard、notdir这几个函数调用,很像变量的使用,也是以“$”来标识的,其语法为:$( )或${ }。参数间以逗号分隔,函数名和参数间以空格分隔。函数调用以“$”开头,以圆括号或花括号把函数名和参数括起。一、subst函数的调用语法$(subst FROM, TO, TEXT),即将字符串TEXT中的子串FROM变为TO。举例:$(subst ...转载 2019-06-04 22:04:56 · 353 阅读 · 0 评论 -
Linux系统编程 -- 为什么需要进程间通信??
进程是一个独立的资源分配单元,不同进程(这里所说的进程通常指的是用户进程)之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源(例如打开的文件描述符)。但是,进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信( IPC:Inter Processes Communication )。进程间通信的目的:数据传输:一个进程需要将它的数据发送给另...原创 2017-03-15 21:46:27 · 3033 阅读 · 0 评论 -
linux系统编程 -- 僵尸进程 孤儿进程
父进程运行结束,但子进程还在运行(未运行结束)的子进程就称为孤儿进程(Orphan Process)。孤儿进程最终会被 init 进程(进程号为 1 )所收养,并由 init 进程对它们完成状态收集工作。在32位系统中为进程号1的进程收养,在64位系统中则不同孤儿进程是没有父进程的进程,为避免孤儿进程退出时无法释放所占用的资源而变为僵尸进程(什么是僵尸进程),进程号为 1 的 ini...原创 2017-03-15 18:45:51 · 314 阅读 · 0 评论 -
Linux系统编程 --- 系统调用
系统调用概述系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务,比如用户可以通过文件系统相关的调用请求系统打开文件、关闭文件或读写文件,可以通过时钟相关的系统调用获得系统时间或设置定时器等。从逻辑上来说,系统调用可被看成是一个内核与用户空间程序交互的接口——它好比一个中间人,把用户进程转载 2017-03-15 11:50:32 · 256 阅读 · 0 评论 -
Linux系统编程——vfork() 函数详解
所需头文件:#include #include pid_t vfork(void);功能:vfork() 函数和 fork() 函数(fork()如何使用,请点此链接)一样都是在已有的进程中创建一个新的进程,但它们创建的子进程是有区别的。参数:无返回值:成功:子进程中返回 0,父进程中返转载 2017-03-15 11:56:47 · 240 阅读 · 0 评论 -
Linux系统编程 -- 可执行文件结构与进程在内存中的分布
一、Linux可执行文件结构在Linux下,程序是一个普通的可执行文件,以下列出一个二进制可执行文件的基本情况:可以看出,此可执行文件在存储时(没有调入到内容)分为代码区(text)、数据区(data)和未初始化数据区(bss)3 个部分。各段基本内容说明如下:代码区:存放 CPU 执行的机器指令。通常代码区是可共享的(即转载 2017-03-15 11:55:00 · 649 阅读 · 0 评论 -
Linux系统编程 -- 文件描述符的复制:dup()和dup2()
dup() 和 dup2() 是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。这个过程类似于现实生活中的配钥匙,钥匙相当于文件描述符,锁相当于文件,本来一个钥匙开一把锁,相当于,一个文件描述符对应一个文件,现在,我们去配钥匙,通过旧的钥匙复制了一把新的钥匙,这样的话,旧的钥匙和新的钥匙都能开启这把锁。对比于 dup(), dup2() 也...原创 2017-03-15 11:52:28 · 246 阅读 · 0 评论 -
Linux系统编程 -- 多线程间同步和互斥
前言线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步、互斥,这些东西将在本文中介绍。我在某QQ群里见到这样一道面试题:是否熟悉POSIX多线程编程技术?如熟悉,编写程序完成如下功能:1)有一int型全局变量g_Flag初始值为0;2) 在主线称中起动线程1,打印“this is thread1”,并将g...原创 2017-03-14 21:21:55 · 401 阅读 · 0 评论 -
进程间通信无名管道 --- pipe 典型的生产者消费者模式
管道的概述管道也叫无名管道,它是是 UNIX 系统 IPC(进程间通信) 的最古老形式,所有的 UNIX 系统都支持这种通信机制。无名管道有如下特点:1、半双工,数据在同一时刻只能在一个方向上流动。2、数据只能从管道的一端写入,从另一端读出。3、写入管道中的数据遵循先入先出的规则。4、管道所传送的数据是无格式的,这要求管道的读出方与写入方必须事先约定好数据的格式,如多少字...转载 2017-03-15 21:48:52 · 615 阅读 · 0 评论 -
进程间通信 --- 命名管道 有名管道存在与内存中,无名管道存在与文件系统中 换种角度看问题
1)open() 以只读方式打开 FIFO 时,要阻塞到某个进程为写而打开此 FIFO open() 以只写方式打开 FIFO 时,要阻塞到某个进程为读而打开此 FIFO。 简单一句话,只读等着只写,只写等着只读,只有两个都执行到,才会往下执行。2)假如 FIFO 里没有数据,调用 read() 函数从 FIFO 里读数据时 read() 也会阻塞。这个特点和无名管道是一样的...原创 2017-03-15 21:49:48 · 1204 阅读 · 1 评论 -
linux 进程间通信 --- 消息队列 消息队列标识符 --- 同一类型 --- 消息头 --- 消息体
概述消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法,其特点如下:1)消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取。2)消息队列允许一个或多个进程向它写入或者读取消息。3)与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删除。4)每个消息队列都有消息队列标识符,消息队列的标识符在整个系统...原创 2017-03-15 21:51:09 · 1105 阅读 · 0 评论 -
进程同步与互斥:POSIX有名信号量
在 POSIX 标准中,信号量分两种,一种是无名信号量,一种是有名信号量。无名信号量一般用于线程间同步或互斥,而有名信号量一般用于进程间同步或互斥。它们的区别和管道及命名管道的区别类似,无名信号量则直接保存在内存中,而有名信号量要求创建一个文件。前面我们学习了无名信号量的使用(详情请看《无名信号量》),这里我们学习有名信号量的使用。1)创建一个有名信号量所需头文件:转载 2017-03-16 14:39:58 · 307 阅读 · 0 评论 -
线程同步与互斥:POSIX无名信号量
信号量概述信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞。PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1。信号量主要用于进程或线程间的同步和互转载 2017-03-16 14:39:26 · 479 阅读 · 0 评论 -
linux 线程同步与互斥:读写锁 线程读操作较多,写操作较少时,使用读写锁
读写锁基本原理当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是由于互斥锁的排它性,所有其它线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会导致问题。在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用...转载 2017-03-16 14:38:38 · 306 阅读 · 0 评论 -
linux 线程同步与互斥:互斥锁 多线程访问共享资源时,使用互斥锁进行控制
为什么需要互斥锁?在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西,如果不做任何处理的话,打印出来的东西肯定是错乱的。下面我们用程序模拟一下这个过程,线程一需要打印“ hello ”,线程二需要打印“ world ”,不加任何处理的话,打印出来的内容会错乱:...转载 2017-03-16 14:37:37 · 980 阅读 · 0 评论 -
Linux系统编程 -- 线程池操作
线程池基本原理在传统服务器结构中,常是有一个总的监听线程监听有没有新的用户连接服务器,每当有一个新的用户进入,服务器就开启一个新的线程用户处理这 个用户的数据包。这个线程只服务于这个用户,当用户与服务器端关闭连接以后,服务器端销毁这个线程。(关于并发服务器更多详情,请看《并发服务器》)。然而频繁地开辟与销毁线程极大地占用了系统的资源,而且在大量用户的情况下,系统为了开辟和销毁线程将浪费大量...原创 2017-03-15 22:59:30 · 226 阅读 · 0 评论 -
Linux系统编程 -- 线程私有属性
在多线程程序中,经常要用全局变量来实现多个函数间的数据共享。由于数据空间是共享的,因此全局变量也为所有线程共有。测试代码如下:#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <stdlib.h> int key = 100; //全局变...原创 2017-03-15 22:58:38 · 493 阅读 · 0 评论 -
Linux系统编程 -- 进程与线程之间差别 进程是系统资源分配的最小单位,线程是进程执行的最小单位
在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体。为了让进程完成一定的工作,进程必须至少包含一个线程。 进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以...原创 2017-03-15 22:53:02 · 4706 阅读 · 0 评论 -
进程间通信---共享内存 ftok shmat shmget shmdt shmctl
概述共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。共享内存的特点:1)共享内存是进程间共享数据的一种最快的方法。一个进程向共享的内存区域写入了数据,共享这个内存区域的所有进程就可以立刻看到其中的内容...转载 2017-03-15 21:52:03 · 565 阅读 · 0 评论 -
守护进程
什么是守护进程?守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行转载 2017-03-15 18:46:47 · 208 阅读 · 0 评论