
Linux操作系统
文章平均质量分 67
记录计算机操作系统学习笔记,主要是linux操作系统
孟小胖_H
本人博客大部分都是在复习中整理的,主要用于记录笔记,其中也记录了一些个人观点和思考,欢迎指点,一起共同学习进步。
展开
-
Linux基本信号的使用
文章目录一、信号的基本概念1.基本信号对应的响应2.信号的值在系统源码中的宏定义二、信号响应方式的修改-signal()1.signal()函数2.signal()函数的使用三、发送信号-kill()1.kill函数原型用于创建内核事件表◼原创 2021-09-27 23:27:17 · 168 阅读 · 0 评论 -
I/O复用函数的使用——poll
1.poll 的接口介绍poll 系统调用和 select 类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者。poll 的原型如下:#include <poll.h>int poll( struct pollfd *fds, nfds_t nfds, int timeout);/*poll 系统调用成功返回就绪文件描述符的总数,超时返回 0,失败返回-1nfds 参数指定被监听事件集合 fds 的大小。timeout 参数指定 poll 的超时值,单位是毫秒原创 2021-09-26 15:07:29 · 234 阅读 · 0 评论 -
I/O复用函数的使用——select
I/O 复用使得程序能同时监听多个文件描述符,这对于提高程序的性能至关重要。通常,网络程序在下列情况下需要使用 I/O 复用技术:◼ TCP 服务器同时要处理监听套接字和连接套接字。◼ 服务器要同时处理 TCP 请求和 UDP 请求。◼ 程序要同时处理多个套接字。◼ 客户端程序要同时处理用户输入和网络连接。◼ 服务器要同时监听多个端口。需要指出的是,I/O 复用虽然能同时监听多个文件描述符,但它本身是阻塞的。并且当多个文件描述符同时就绪时,如果不采取额外的措施,程序就只能按顺序依处理其中的每一个原创 2021-09-25 19:35:39 · 218 阅读 · 0 评论 -
socket网络编程——UDP编程流程
UDP 提供的是无连接、不可靠的、数据报服务。编程流程如下:socket()方法用来创建套接字,使用udp协议时,选择数据报服务SOCK_DGRAM。sendto()方法用来发送数据,由于 UDP 是无连接的,每次发送数据都需要指定对端的地址(IP 和端口)。recvfrom()方法接收数据,每次都需要传给该方法一个地址结构来存放发送端的地址。recvfrom()方法可以接收所有客户端发送给当前应用程序的数据,并不是只能接收某一个客户端的数据。UDP服务端代码:#include<stdi原创 2021-09-25 12:02:13 · 1828 阅读 · 0 评论 -
socket网络编程——多进程、多线程处理并发
1.服务器处理并发的必要性如下图所示, 当一个客户端与服务器建立连接以后,服务器端 accept()返回,进而准备循环接收客户端发过来的数据。如果客户端暂时没发数据,服务端会在 recv()处阻塞。此时,其他客户端向服务器发起连接后,由于服务器阻塞了,无法执行 accept()接受连接,也就是其他客户端发送的数据,服务器无法读取。服务器也就无法并发同时处理多个客户端。这个问题可以通过引入多线程和多进程来解决。服务端接受一个客户端的连接后,创建一个线程或者进程,然后在新创建的线程或进程中循环处理数据。主原创 2021-09-25 11:21:39 · 5272 阅读 · 0 评论 -
socket网络编程——TCP编程流程及端口号占用问题
1.TCP编程流程1.1TCP服务器端客户端及方法介绍TCP 提供的是面向连接的、可靠的、字节流服务。TCP 的服务器端和客户端编程流程如下:socket()方法是用来创建一个套接字,有了套接字就可以通过网络进行数据的收发。这也是为什么进行网络通信的程序首先要创建一个套接字。创建套接字时要指定使用的服务类型,使用 TCP 协议选择流式服务(SOCK_STREAM)。bind()方法是用来指定套接字使用的 IP 地址和端口。IP 地址就是自己主机的地址,如果主机没有接入网络,测试程序时可以使用回环地原创 2021-09-25 09:00:27 · 3458 阅读 · 3 评论 -
socket网络编程——网络编程接口
网络编程接口#include <sys/types.h>#include <sys/socket.h>/*socket()创建套接字,成功返回套接字的文件描述符,失败返回-1domain: 设置套接字的协议簇, AF_UNIX AF_INET AF_INET6type: 设置套接字的服务类型 SOCK_STREAM SOCK_DGRAMprotocol: 一般设置为 0,表示使用默认协议*/int socket( int domain, int type, int原创 2021-09-24 21:35:24 · 276 阅读 · 0 评论 -
socket网络编程——套接字地址结构
声明:此博客是本人根据老师课件总结的,如有抄袭行为,本人会即刻删除。1.主机字节序列和网络字节序列主机字节序列分为大端字节序和小端字节序,不同的主机采用的字节序列可能不同。大端字节序是指一个整数的高位字节存储在内存的低地址处,低位字节存储在内存的高地址处。小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地址处。在两台使用不同字节序的主机之间传递数据时,可能会出现冲突。所以,在将数据发送到网络时规定整形数据使用大端字节序,所以也把大端字节序成为网络字节序列。对方接收到数据后,原创 2021-09-24 21:22:00 · 359 阅读 · 0 评论 -
LInux线程——多线程与fork之间的问题
1.多线程中某个线程调用 fork(),子进程会有和父进程相同数量的线程吗?1.1fork在创建线程前pthread_fork1.c代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<assert.h>#include<pthread.h>void* pthread_fun(void* arg){原创 2021-09-22 23:35:01 · 1671 阅读 · 0 评论 -
Linux线程——线程同步
线程同步指的是当一个线程在对某个临界资源进行操作时,其他线程都不可以对这个资源进行操作,直到该线程完成操作,其他线程才能操作,也就是协同步调,让线程按预定的先后次序进行运行。线程同步的方法有四种:互斥锁、信号量、条件变量、读写锁。1.互斥锁头文件及函数声明:#include <pthread.h>/*mutex是锁,attr是锁的属性,一般用不上,传个NULL默认属性就可以*/int pthread_mutex_init(pthread_mutex_t *mutex, pthre原创 2021-09-24 20:50:54 · 696 阅读 · 0 评论 -
Linux线程——线程安全问题
线程安全即就是在多线程运行的时候,不论线程的调度顺序怎样,最终的结果都是一样的、正确的。那么就说这些线程是安全的。要保证线程安全需要做到:(1) 对线程同步,保证同一时刻只有一个线程访问临界资源。(2)在多线程中使用线程安全的函数(可重入函数),所谓线程安全的函数指的是:如果一个函数能被多个线程同时调用且不发生竟态条件,则我们程它是线程安全的。可重入函数:就是输入一定的情况下,输出结果必然固定,而且从逻辑上讲要正确,不受任何其他情况的影响。所以可重入函数不能用全局变量、静态变量。我们期待这样一件事原创 2021-09-22 22:36:18 · 294 阅读 · 0 评论 -
Linux线程——线程创建和基本使用(多线程并发)
1.线程的概念与实现方式1.1 线程的概念概念:线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程。线程是进行资源调度和分配的基本单位 。(1)每个进程至少有一条执行路径,所以一个进程至少有一个进程。(2)每个进程都有一个主线程。1.2 线程的实现方式在操作系统中,线程的实现有以下三种方式:(1)用户级线程:由线程库中的代码进行管理,处理 ,销毁。用户自己创建的多线程,即多个处理路径,无法使用多处理器的资源,在内核眼里就只是一条路径。(2)内核级线程:由内核直接创建、直接管理原创 2021-09-24 17:23:45 · 18507 阅读 · 0 评论 -
进程间通信——消息队列
1.消息队列原理1、2…是消息类型,进程发送消息可以指定消息类型,进程接收消息也指定消息类型,这样在消息队列里识别消息类型就可以知道是不是自己需要接受的消息了。2.消息队列示例代码函数介绍:#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>/*msgget()创建或者获取一个消息队列msgget()成功返回消息队列 ID,失败返回-1msqflg: IPC_CREAT*/i原创 2021-09-22 12:49:23 · 282 阅读 · 0 评论 -
进程间通信——共享内存
1. 共享内存原理共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进程向共享内存写入了数据,所做的改动将立刻被可以访问同一段共享内存的任何其他进程看到。由于它并未提供同步机制,所以我们通常需要用其他的机制来同步对共享内存的访问。(1)写入共享内存后,数据不会消失,可以一直读取。(2)再次向共享内存写入数据后,会覆盖共享内存之前原创 2021-09-22 09:25:51 · 872 阅读 · 0 评论 -
进程间通信——信号量及ipcs/ipcrm 介绍
1.信号量描述信号量是用来同步进程的(即控制进程的执行),是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目。获取资源时,需要对信号量的值进行原子减一,该操作被称为 P 操作。当信号量值为 0 时,代表没有资源可用,P 操作会阻塞。释放资源时,需要对信号量的值进行原子加一,该操作被称为 V操作。信号量主要用来同步进程。信号量的值如果只取 0,1,将其称为二值信号量。如果信号量的值大于 1,则称之为计数信号量。临界资源:同一时刻,只允许被一个进程或线程访问的资源临界区:访问临界资源的代码段2原创 2021-09-21 19:10:18 · 840 阅读 · 0 评论 -
进程间通信(IPC机制)——管道
1.管道的特点(1)无论有名还是无名,写入管道的数据都在内存中。(2)管道是一种半双工通信方式(通信方式有单工(固定接收方发送方,接收方只能接收,发送方只能发送)、半双工(如同对讲机,两端可以切换写入和接收)、全双工(每端都可以接收和写入,且可以同时进行))。(3)有名和无名管道的区别:有名可以在任意进程间使用,而无名只能在父子进程间。(4)对于管道,我们只能以只读打开或者只写打开。(5)有名管道得需要读和写都打开,否则只以读打开或者只以写打开都会阻塞。(6)管道中没有数据时,读管道read会发原创 2021-09-21 10:38:38 · 565 阅读 · 0 评论 -
Linux信号的使用
1、信号的基本概念信号是系统响应某个条件而产生的事件,进程接收到信号会执行相应的操作。与信号有关的系统调用在“signal.h”头文件中有声明。常见信号的值,及对应的功能说明:信号的值在系统源码中的定义如下:#define SIGHUP 1#define SIGINT 2 //键盘按下 Ctrl+c 时,会产生该信号#define SIGQUIT 3#define SIGILL 4#define SIGTRAP 5#define SIGABRT 6#define SIGIOT 6#d原创 2021-09-20 21:49:26 · 207 阅读 · 0 评论 -
exec进程替换
1.exec 系列替换过程:pcb 使用以前的只修改,进程实体更换。我们在linux系统上写的进程都会经过bash的fork产生PCB和进程块,再利用进程替换,将进程块替换为新的进程。所以我们写的程序(除去我们在自己的进程fork的进程)查看父进程会发现都是bash。头文件:#include <unistd.h>/**path:新替换的程序的路径名称*arg :传给新程序主函数的第一个参数,一般为程序的名字*arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数*/原创 2021-09-20 19:52:31 · 251 阅读 · 0 评论 -
孤儿进程和僵死进程处理方法
1.僵死进程僵死进程概念:子进程先于父进程结束,父进程没有调用 wait 获取子进程退出码。如何处理僵死进程:父进程通过调用 wait()完成。1.1僵死进程展示运行以下代码:运行结果:从上图中可以看到,当子进程结束后,并没有消失,仍然可以在系统中观测到,但此时子进程其实已经运行结束了,此时子进程的状态被称为僵死状态,系统把处于该类状态的进程称为僵死进程。 如果父进程先结束,子进程最后是不会变为僵死进程的。1.2僵死进程的解决利用wait解决 ,wait获取子进程退出码即可。下图是wa原创 2021-09-20 12:47:17 · 461 阅读 · 0 评论 -
fork与操作文件的系统调用问题
1.打开文件int open(const char* pathname, int flags)//用于打开一个已存在的文件int open( const char* * pathname, int flags,mode_t mode);//用于新建一个文件,并设置访问权限参数介绍:pathname:将要打开的文件路径和名称flags : 打开标志,如 O_WRONLY 只写打开O_RDONLY 只读打开O_RDWR 读写方式打开O_CREAT 文件不存在则创建O_APPEND 文件末尾追原创 2021-09-20 10:03:11 · 248 阅读 · 0 评论 -
fork练习、从进程角度考虑堆区内存申请与释放的有关问题
1.fork练习代码1;int main( int argc, char* argv[], char* envp[]){ int i = 0; for( ; i < 2; i++ ) { fork(); printf("A\n"); } exit(0);}输出几个A?在这里只需要简单分析就出结果。如图:0为最初程序,0-1为0的子进程,0-1-1为0-1的子进程…简单分析可知总共产生了4个进程。0进程肯定输出2A;0-1进程由于0产生此子进程时i = 0,且打印A在创原创 2021-09-19 23:32:52 · 543 阅读 · 0 评论 -
fork复制进程
1.fork方法的定义pid_t fork(void) ;函数返回类型 pid_t 实质是 int 类型,Linux 内核 2.4.0 版本的定义是:fork 函数会新生成一个进程,调用 fork 函数的进程为父进程,新生成的进程为子进程。在父进程中返回子进程的 pid,在子进程中返回 0,失败返回-1。...原创 2021-09-19 22:09:54 · 282 阅读 · 0 评论 -
printf函数与主函数问题
1、printf 函数输出问题printf 函数并不会直接将数据输出到屏幕,而是先放到缓冲区中,只有一下三种情况满足,才会输出到屏幕。1) 缓冲区满2) 强制刷新缓冲区 fflush(缓冲区遇到\n会自动刷新)3) 程序结束时运行printf可执行程序时,我们发现,它会“先执行”sleep(2)再打印hello。注意先执行我们打了双引号的,其实并不是先执行了sleep(2)。程序执行printf时将需要输出的字符放到了缓冲区中了,此时由于缓冲区没有满,也没有刷新缓冲区,程序也没有结束,所以才没有原创 2021-09-19 20:34:54 · 459 阅读 · 0 评论 -
计算机基础
1、计算机的基本组成1.1 计算机组成五大部件(1) 运算器 :也叫算数逻辑单元,完成对数据的各种常规运算,如加减乘除,也包括逻辑运算,移位,比较等。(2) 控制器 : 它是整个计算机系统的控制中心,它指挥计算机各部分协调地工作,保证计算机按照预先规定的目标和步骤有条不紊地进行操作及处理。(3) 存储器 :存储程序和各种数据。存储器一般大小(存储速度升序)硬盘 > 内存 > cache缓存 > 寄存器(4) 输入设备 :把人所熟悉的信息如,图片,声音,文字,转换为计算机能够识原创 2021-09-19 19:50:03 · 689 阅读 · 0 评论 -
Linux系统上的库文件的生成与使用
1.什么是库文件库是一组预先编译好的方法的集合。Linux系统存储的库的位置一般在:/lib 和 /usr/lib。在 64 位的系统上有些库也可能被存储在/usr/lib64 下。库的头文件一般会被存储在/usr/include 下或其子目录下。库有两种,一种是静态库,其命令规则为 libxxx.a,一种是共享库,其命令规则为 libxxx.so,如下图所示:2.静态库的生成与使用2.1 静态库的生成首先看add.c、max.c、foo.h的内容第一步:先将需要生成库文件的所有“.c“原创 2021-09-19 15:22:45 · 263 阅读 · 0 评论 -
gdb调试的用法
1.Debug 版本和 Release 版本1.1Debug 版本Debug 版本为可调式版本,生成的可执行文件中包含调试需要的信息。我们作为开发人员,最常用的就是 debug 版本的可执行文件。Debug 版本的生成:因为调试信息是在编译过程时加入到中间文件(.o)中的,所以必须在编译时控制其生成包含调试信息的中间文件。gcc -c hello.c -g —> 生成包含调试信息的中间文件gcc -o hello hello.o或者 gcc -o hello hello.c -g1原创 2021-09-19 13:45:14 · 335 阅读 · 0 评论 -
makefile与make
makefile与make做了对文件的编译链接,我们只需要写一个makefile文件,执行make就会生成我们所需要的可执行文件,下面演示makefile的代码和操作:例如:对 main.c add.c max.c 三个文件进行编译(注意: gcc 前面必须是 table 建缩进)首先我们先看看main.c、add.c、max.c文件内容:接下来完成makefile文件的操作:1.关于makefile里的clean注意最后一行故意写成了clear,make clear就可以删除当前路径下mai原创 2021-09-19 13:04:14 · 461 阅读 · 0 评论 -
gcc编译器及编译链接过程
1.gcc分步编译链接:(1) 预编译 :gcc -E main.c -o main.i(2) 编译:gcc -S main.i -o main.s(3) 汇编:gcc -c main.s -o main.o//windows上为main.obj文件(4) 链接:gcc main.o -o main一般我们直接一步到位:gcc -o main mian.c2.编译连接过程2.1预编译阶段a) 删除所有的“#define”,并且展开所有的宏定义;b) 处理所有的条件预编译指令,“原创 2021-09-19 11:00:46 · 2489 阅读 · 2 评论