系统编程
文章平均质量分 51
Linux系统编程
干锅土鸡
这个作者很懒,什么都没留下…
展开
-
信号量概述与相关函数分析
信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负的整数计数器,它被用来控制对公共资源的访问。编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量值大于 0 时,则可以访问,否则将阻塞。PV 原语是对信号量的操作,一次 P 操作使信号量减1,一次 V 操作使信号量加1。信号量主要用于进程或线程间的同步和互斥这两种典型情况。信号量数据类型为:sem_t。信号量用于互斥:信号量用于同步:...原创 2022-01-07 22:51:19 · 281 阅读 · 0 评论 -
条件变量、生产者消费者模型
与互斥锁不同,条件变量是用来等待而不是用来上锁的,条件变量本身不是锁!条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。条件变量的两个动作:条件不满, 阻塞线程当条件满足, 通知阻塞的线程开始工作条件变量的类型: pthread_cond_t。生产者消费者模型:#include<stdio.h>#include<stdlib.h>#include <string.h>#include <unist原创 2022-01-07 21:00:16 · 454 阅读 · 0 评论 -
读写锁概述
当有一个线程已经持有互斥锁时,互斥锁将所有试图进入临界区的线程都阻塞住。但是考虑一种情形,当前持有互斥锁的线程只是要读访问共享资源,而同时有其它几个线程也想读取这个共享资源,但是由于互斥锁的排它性,所有其它线程都无法获取锁,也就无法读访问共享资源了,但是实际上多个线程同时读访问共享资源并不会导致问题。在对数据的读写操作中,更多的是读操作,写操作较少,例如对数据库数据的读写应用。为了满足当前能够允许多个读出,但只允许一个写入的需求,线程提供了读写锁来实现。读写锁的特点如下:1)如果有其它线程读数据,则允原创 2022-01-07 15:28:53 · 2374 阅读 · 0 评论 -
Linux互斥锁和代码实现、死锁
互斥锁Mutex在线程里也有这么一把锁:互斥锁(mutex),也叫互斥量,互斥锁是一种简单的加锁的方法来控制对共享资源的访问,互斥锁只有两种状态,即加锁( lock )和解锁( unlock )。互斥锁的操作流程如下:在访问共享资源后临界区域前,对互斥锁进行加锁。在访问完成后释放互斥锁导上的锁。对互斥锁进行加锁后,任何其他试图再次对互斥锁加锁的线程将会被阻塞,直到锁被释放。互斥锁的数据类型是: pthread_mutex_t。pthread_mutex_initrestric原创 2022-01-06 23:29:19 · 283 阅读 · 0 评论 -
线程分离、线程退出、线程属性、线程栈地址
线程分离一般情况下,线程终止后,其终止状态一直保留到其它线程调用pthread_join获取它的状态为止。但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join,这样的调用将返回EINVAL错误。也就是说,如果已经对一个线程调用了pthread_detach就不能再调用pthread_join了。线程退出在进程中我们可以调用exit函数或_exit函数来结束进程,在一个线程中我们可以原创 2022-01-04 01:36:49 · 671 阅读 · 1 评论 -
线程概念、优缺点、线程函数
在许多经典的操作系统教科书中,总是把进程定义为程序的执行实例,它并不执行什么, 只是维护应用程序所需的各种资源,而线程则是真正的执行实体。所以,线程是轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程。为了让进程完成一定的工作,进程必须至少包含一个线程。进程,直观点说,保存在硬盘上的程序运行以后,会在内存空间里形成一个独立的内存体,这个内存体有自己的地址空间,有自己的堆,上级挂靠单位是操作系统。操作系统会以进程为单位,分配系统资源,所以我们也说,进程是原创 2022-01-04 00:25:56 · 209 阅读 · 0 评论 -
守护进程、守护进程创建代码实现、获取系统时间
守护进程介绍守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程。它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用以d结尾的名字。守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行原创 2022-01-03 15:06:21 · 551 阅读 · 0 评论 -
终端和进程组概念、会话
终端输入sleep 3000,和sleep 3000 &的区别前者无法继续解析用户输入的命令,后者可以(sleep成为后台进程)在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal),进程中,控制终端是保存在PCB中的信息,而fork会复制PCB中的信息,因此由Shell进程启动的其它进程的控制终端也是这个终端。默认情况下(没有重定向),每个进程的标准输入、标准输出和标准错误输出都指向控制终端,进程从标准原创 2022-01-03 00:56:41 · 720 阅读 · 0 评论 -
不可重入和可重入函数概述、使用信号避免僵尸进程
如果有一个函数不幸被设计成为这样:函数体内使用了静态的数据结构;函数体内调用了malloc() 或者 free() 函数(谨慎使用堆);函数体内调用了标准 I/O 函数。(缓冲区)那么不同任务调用这个函数时可能修改其他任务调用这个函数的数据,从而导致不可预料的后果。这样的函数是不安全的函数,也叫不可重入函数。相反,肯定有一个安全的函数,这个安全的函数又叫可重入函数。那么什么是可重入函数呢?所谓可重入是指一个可以被多个任务调用的过程,任务在调用时不必担心数据是否会出错。保证函数的可重入性的方法:原创 2022-01-02 15:18:57 · 346 阅读 · 0 评论 -
信号的处理方式、sigaction函数
一个进程收到一个信号的时候,可以用如下方法进行处理:执行系统默认动作对大多数信号来说,系统默认动作是用来终止该进程。忽略此信号(丢弃)接收到此信号后没有任何动作。执行自定义信号处理函数(捕获)用用户定义的信号处理函数处理该信号。【注意】:SIGKILL 和 SIGSTOP 不能更改信号的处理方式,因为它们向用户提供了一种使进程终止的可靠方法。sigaction函数#include <stdio.h>#include <stdlib.h>#includ原创 2022-01-02 02:20:22 · 321 阅读 · 0 评论 -
信号集和信号集操作函数、信号屏蔽集设置和演示
阻塞信号集可以读写、未决信号集只能读不能写信号集操作函数为了方便对多个信号进行处理,一个用户进程常常需要对多个信号做出处理,在 Linux 系统中引入了信号集(信号的集合)。这个信号集有点类似于我们的 QQ 群,一个个的信号相当于 QQ 群里的一个个好友。信号集是一个能表示多个信号的数据类型,sigset_t set,set即一个信号集。既然是一个集合,就需要对集合进行添加/删除等操作。#include <stdio.h>#include <stdlib.h>#incl.原创 2022-01-02 01:13:48 · 224 阅读 · 0 评论 -
signal函数实现信号、超时信号的捕捉
超时信号的捕捉#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <signal.h>void fun(int signo){ printf("捕捉到信号:%d\n",signo);}int main(){ int ret=-1; struct itimerval tmo; //第一次触发时间...原创 2022-01-01 22:57:52 · 428 阅读 · 0 评论 -
信号的概述、kill、raise、abort、alarm、setitimer
信号概念信号是 Linux 进程间通信的最古老的方式(有名管道、无名管道、信号)。信号是软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式 。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。“中断”在我们生活中经常遇到,譬如,我正在房间里打游戏,突然送快递的来了,把正在玩游戏的我给“中断”了,我去签收快递( 处理中断 ),处理完成后,再继续玩我的游戏。这里我们学习的“信号”就是属于这么一种“中断”。我们在终端上敲“Ctrl+c”,就产生一个“中断原创 2022-01-01 14:48:31 · 710 阅读 · 0 评论 -
匿名映射实现父子进程通信
这个宏不能单独使用,要联合使用原创 2021-12-31 16:02:39 · 700 阅读 · 0 评论 -
共享存储映射mmap
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <sys/mman.h>//存储映射int main(){ int fd=-1; int r...原创 2021-12-28 01:04:37 · 434 阅读 · 0 评论 -
有名管道fifo
1. 概述管道,由于没有名字,只能用于亲缘关系的进程间通信。为了克服这个缺点,提出了命名管道(FIFO),也叫有名管道、FIFO文件。命名管道(FIFO)不同于无名管道之处在于它提供了一个路径名与之关联,以 FIFO 的文件形式存在于文件系统中,这样,即使与 FIFO 的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过 FIFO 相互通信,因此,通过 FIFO 不相关的进程也能交换数据。命名管道(FIFO)和无名管道(pipe)有一些特点是相同的,不一样的地方在于:FIFO 在文件原创 2021-12-23 13:18:10 · 941 阅读 · 0 评论 -
进程间通信(无名管道)
管道管道也叫无名管道,它是是 UNIX 系统 IPC(进程间通信) 的最古老形式,所有的 UNIX 系统都支持这种通信机制。管道有如下特点:半双工,数据在同一时刻只能在一个方向上流动。数据只能从管道的一端写入,从另一端读出。写入管道中的数据遵循先入先出的规则。管道所传送的数据是无格式的,这要求管道的读出方与写入方必须事先约定好数据的格式,如多少字节算一个消息等。管道不是普通的文件,不属于某个文件系统,其只存在于内存中。管道在内存中对应一个缓冲区。不同的系统其大小不一定相同。从管道读数..原创 2021-12-20 17:57:51 · 801 阅读 · 0 评论 -
孤儿、僵尸进程、进程替换exec函数族
孤儿进程init的pid为1(字符界面的Linux是1号进程,图形界面的Linux不是1号进程,Ubuntu为10791进程)父进程退出后,子进程的父进程从58161变成了1号进程(init)僵尸进程僵尸进程!(Z)execlp进程替换可以看到没有输出hello world,解析:没有创建新进程,镜像替换而已。将原进程数据全部替换成新可执行文件数据。进程数据被全部替换后,又会从main函数开始执行。...原创 2021-12-16 21:33:11 · 148 阅读 · 0 评论 -
进程退出函数
exit(0)等价于return 0,只是多了刷新缓冲区等(友好退出)_exit(0)或者_Exit(0)不刷新缓冲区:(直接退出,不做事后清理工作,强行退出)上述代码输出不了hello world原创 2021-12-15 23:36:15 · 1045 阅读 · 0 评论 -
父子进程地址空间、堆空间
读时共享,写时拷贝(全部变量和局部、堆空间都是这样的结果)堆区,申请一次,必须释放两次。因为子进程也复制了一份去。父子进程申请的堆空间地址是一样的。Linux中查看内存泄漏的工具:valgrind ./a.out上面代码内存泄漏!改进:两个进程都加上:free§GDB调试多进程-g别忘了默认跟踪父进程!若要跟踪子进程,则需要设置:在执行到fork前,加上这句 set follow-fork-mode child...原创 2021-12-15 01:47:16 · 314 阅读 · 0 评论 -
进程相关函数理解
进程号(PID):标识进程的一个非负整数父进程号(PPID):任何进程(除init进程)都是由另一个进程创建,该进程称为称为被创建的进程的父进程,对应的进程号为(PPID),如:A进程创建了B进程,A的进程号就是B进程的父进程号。进程组号(PGID):进程相关函数getpid() getppid() getpgid()子进程号会变,父进程号每次都一样(父进程就是命令解析器:bash),进程组(当前进程组中只有一个进程,所以进程组号就是进程号)创建进程更准确来说,Linux原创 2021-12-13 22:11:45 · 443 阅读 · 0 评论 -
进程、fork创建、PID获取
PCB(进程控制块)进程标识符PID,从cpu获得时间片,就会从就绪状态R转换成运行状态R包含的信息比上述包含的多得多…原创 2021-12-13 20:29:48 · 562 阅读 · 0 评论 -
ext2文件系统
文件系统的定义文件系统功能:管理和调度文件的存储空间,提供文件的逻辑结构、物理结构和存储方法,实现文件从标识到实际地址的映射,实现文件的控制操作和存储操作,实现文件信息的共享并提供可靠的文件保密和保护措施,提供文件的安全措施。windows常用文件系统格式:fat32,fat16,ntfsLinux常用的是:ext2、ext3、ext4、Linuxswap和VFAT读写的最小单位是一个扇区,512字节。一个块一般是扇区的整数倍。GDT(group descriptor t..原创 2021-11-23 21:10:47 · 902 阅读 · 0 评论 -
fcntl
access():检查是否可以对某个文件执行某种操作F_OK 值为0,判断文件是否存在X_OK 值为1,判断对文件是可执行权限W_OK 值为2,判断对文件是否有写权限R_OK 值为4,判断对文件是否有读权限注:后三种可以使用或“|”的方式,一起使用,如W_OK|R_OKargv[0]:当前的命令 argv[1]:传入的文件名fcntl():现在是标准输入为阻塞模式,也就是会卡住通过这个函数把标准输入改成非阻塞第三个参数的处理原理:...原创 2021-11-23 00:10:10 · 117 阅读 · 0 评论 -
lseek
启动一个进程之后,内核空间做了很多地工作,首先创建一个结构体:struct task_struct,每个进程都会有一个PCB(process control block):进程控制块。结构体中有一个文件描述符表,专门用来存放文件描述符。默认是0 1 2,自己打开后从3开始。最大为1023,因为最多只有1024个。表中还有file结构体指针,内容为:flags(只读只写等)、Pos(位置)、指向文件。file结构体是在内核空间中申请的。off_t:用于文件偏移,long类型lseek函数:f..原创 2021-11-22 01:28:31 · 215 阅读 · 0 评论 -
open、read、write函数
C语言中的文件函数是在用户空间中创建8K的缓冲区,fopen返回的是FILE* 的指针(地址),而open这类函数是介于内核和用户空间之间,open返回的是非负整数:当前进程的文件描述符。这并不是重载,而是变参函数(C语言知识点):int open(const char* pathname,int flags, … );flags有三个可选项,及权限:perror:打印出错信息strerror(errno):打印出错信息(返回字符串)...原创 2021-11-22 00:27:37 · 1177 阅读 · 0 评论 -
Linux基本文件IO/open/write
Linux系统编程/网络编程基本内容:fopen返回的是FILE* 的指针FILE是个结构体,fopen fread fwrite fclose 这些属于C语言open read write close 属于系统调用返回的是文件描述符:非负整数 file description:fdC标准函数内部也是应用函数描述符buffer意义在于避免反复操作磁盘文件,内存速度大于磁盘速度open是可变参函数,并不是C++中的函数重载open成功会返回文件描述符,失败会返回-1p.原创 2021-11-21 23:53:14 · 515 阅读 · 0 评论