襄阳网站建设楚翼网络wordpress 云主机 ssl

当前位置: 首页 > news >正文

襄阳网站建设楚翼网络,wordpress 云主机 ssl,如何确定网站被k,微信嵌入网站开发两个进程间想通讯#xff0c;必须要通过内核#xff0c;今天讲的信号其实本质也是讲进程间通讯的意思#xff0c;那么你为什么可以在shell环境下#xff0c;可以和一个进程发kill-9啊#xff1f; shell是不是相当于一个进程#xff1f;你自己运行的那个进程是不是也相当于… 两个进程间想通讯必须要通过内核今天讲的信号其实本质也是讲进程间通讯的意思那么你为什么可以在shell环境下可以和一个进程发kill-9啊 shell是不是相当于一个进程你自己运行的那个进程是不是也相当于一个进程这样的话是不是一个进程给另外一个进程发送信号啊他本质上也是进程间通讯也是需要通过内核 作业在父子进程间执行psux的命令啊 在兄弟进程间完成这么一个功能同时增加别的功能 父进程里面是不是需要回收啊回收子进程 这个代码你看一下你到底哪里没写出来 我们完成的功能是psux groupby里面的命令吧 所以说咱们应该是在创建子进程之前应该创建一个管道啊这样的话fork出这两个子进程以后呢这两个子进程是不是都可以使用这两个管道了啊 实际上在使用管道的时候呢是不是就使用了两个文件描述符啊我们操作管道是不是其实就是操作两个文件描述符的 在循环里面创建了两个子进程在36为什么加break 为了让子进程不再去fork子进程 循环创建两个子进程 这个wpid0 这个是不是表示子进程已经死掉了至少死掉了一个至少你可以调用这个宏打印一下他的退出状态65–71 父进程做的事情就是这么些个这一块咱们前面是不是写过两三次了 第一个子进程 i0 79 我们的目的是让他往管道里面写吧他执行ps aux 这个命令 这一个和接下来的这一块是不是和咱们前面讲的那个图是一模一样的只不过是把那个父进程变成子进程吧 所以说他用哪端就留哪端不用哪端就关闭哪端在这他用的是管道的写端所以他关闭的是管道的读端 他执行的dup2这个函数 是不是可以实现文件重定向啊文件重定向和文件描述符的复制本身上是不是一个意思啊两个说法而已 那么他要将谁重定向谁是不是应该是把标准输出重定向到管道的写端啊所以这一步操作就是干这一个事情的这一步操作是不是前面咱们说过两三次了还记的将标准输出重定向到文件当中去吗那个只不过fd[1]是一个open打开的一个文件啊在这他是个管道 本质上是不是一样的啊 在这执行了一个命令 execlp这个命令 86这个命令内核当中所做的操作是不是其实是将ps这个命令他的代码端是不是替换掉了当前这个子进程的代码段啊如果说这个函数执行成功后面perror这个函数还能执行吗 87 89不能执行了其实 如果成功 后面这个相当于废话冗余代码 后面可以没有那是不是不用写了因为他有可能失败那你比如说你这个ps你写错了或者你的参数不对都有可能会报错出于习惯你把这个写上 89 万一报错的话你是不是可以看到啊如果你不写你就不知道了 看第二个子进程i1 第二个子进程 很显然是不是他要执行管道右边的group bash的命令啊 所以说在这呢也应该是做重定向操作吧当然用哪端留哪端不用哪端关哪端在这他是不是用读端所以他关掉了写端接下来是不是和咱们前面讲过的一模一样了 然后他也做了一个重定向后面来执行一个命令这个execlp一定要会用100  这个函数其实execlp还可以被这个execl函数代替啊 如果你代替之后那么你第一个参数是不是要加路径了怎么查看这个命令的路径啊 which  你这个用命令查的话是不是只能查这个系统命令的这个路径你能查这个普通用户写的这个应用程序的路径吗查不了了 这个代码应该说有一定的综合性在这里咱们综合用到了 创建管道 fork  循环创建子进程的时候需要你注意的事项 父进程回收子进程 waitpid waitpid 函数的使用务必要搞清楚 还有这几个状态的宏65 71 这几个状态的宏你记不住你就查man  waitpid  文件重定向操作在一个子进程里面执行另一个命令另一个系统命令或者是应用程序的函数execl的函数 综合应用了这些东西应该是这个代码应该说这个如果大家掌握了咱们前面讲过的那个父子进程间完成ps aux 这样的一个命令的话呢那么我想在兄弟之间完成也不难而且咱们这个wpid是不是前面也学过了如何让父进程回收子进程大致也会了其实就是两段代码一组合就可以了 看懂代码之后看看是否符合自己的需求不符合的话拿过来大概改一改就可以用了一般就这么用的很少会让你从零开始写即便是从零开始写我想的话应该是会有大概的模板比如说这个代码和这个代码类似你照着他写就可以了一般这么来写如果说研发一个产品的话从零开始写那么周期会很长 他能够用现实的东西比如说库函数现成的类等等他就用现成的 共享映射区他的实现原理将文件内容映射到共享映射区那么这样的话你再操作这块内存是不是就相当于操作这个文件啊那么我们这个共享映射区其实就是一共有两个类一个是MAP_SHARED 一个是MAP_PRIVATE那其中MAP_SHARED是不是能够将修改内存的数据反应到文件当中去但是MAP_PRIVATE就不行了一般时候用的话就用MAP_SHARED就可以了 这个关于mmap函数的用法咱们就不过多的说了那么这个函数呢虽然说参数比较多但是很多参数都是有固定写法的那么唯一有那么一两个让你准备的 是不是就那个文件描述符了还有文件大小其他的要你准备吗都是现成的直接填就可以了mmap他不但能够完成父子进程间或者兄弟进程间也就是有血缘关系的进程间通讯是不是也能够完成没有任何关系的两个进程间通讯啊当然你要想让他完成任何两个进程通讯的话必须有一个文件 还有一个匿名映射大家了解一下就可以了匿名映射是不是只能运用于有血缘关系的进程间通讯啊因为他没有文件如果两个毫不相干的进程他就没有联系的纽带 那么关于这个fifo 是不是更简单了fifo是不是你得用一个文件啊管道文件这个管道文件是不是咱们操作系统里面的系统文件类型是一样第一个字母是p 那么这样的话必须是文件那么两个进程通过打开一个共同的文件来操作这个管道 基本上复习的文件就这么多 熟练使用信号捕捉函数 sigaction 重点掌握 熟练使用信号捕捉函数 sigrtal 这个不能跨平台移植只能在linux上使用在其他系统中呢他表现的行为有所区别 sigaction都是一样的可移植的 你在linux写这个用这个那么你拿到unixs上不做任何修改也可以但是用sigrtal这个的话就不一定了 熟练掌握使用信号完成子进程的回收  是本章的重点 前面讲回收是不是父进程在一个循环里面去循环回收啊那么循环回收还能做其他的事情吗是不是做不了啊这儿就可以了 也就是说有子进程 有子进程退出他才去回收没有子进程退出他不管有点类似于 你在网上买的货你是不是要在家等着货过来呀你不可能一会往那跑一趟 一会往那跑一趟去问吧人家打电话你去拿就可以了 最终是不是异步处理啊你并不知道你的货什么时候到对于这个来说你并不知道你的子进程什么时候死 信号是信息的载体 在c语言当中结构体是不是也是信息的载体 Linux/UNIX 环境下古老、经典的通信方式这个信号已经出了很长时间了他不是一个新的技术早就有了现在依然是主要的通信手段 这个信号仍然是两个进程通信的主要手段之一 信号的优先级高 不管程序执行了什么位置只要是有信号发生了优先处理信号信号处理完以后呢再回过头来再执行刚才是从哪中断的从哪执行 信号是软件层面的中断被称为软中断 程序一开始运行在用户区运行的时候有的时候需要接触到内核啊下面是内核区 进程a要想给进程b发送一个信号首先他其实进程a是发给了内核然后由内核再给你转发给进程B  进程a先发给内核然后内核再转给b 那么内核怎么知道转给b 你发信号的时候你kill 你会写一个 当然第一个肯定要写一个哪个信号吧要发哪个信号 给哪个进程发哪个信号是不是至少两个信息啊一个是进程pid 一个是进程的编号吧信号的编号 所以说你指定了进程的pid了那么这样的话其实是你先告诉内核的吧你这个进程a kill的时候你已经告诉内核了你要给谁发送信号那么内核是不是就知道给谁转发了所以说 他知道转给b 是不是返回来也是一样的把进程b给进程a是不是也是这样的 比如说我这个里面是我们这个方块是我们的代码执行到这个位置了突然发生了信号他是不是优先处理这个信号啊这样处理信号在这我们画一个我们写的处理信号的动作是执行一个函数 这个函数是我们自己写的用的是回调函数这个信号处理函数   也就是我们在处理信号的意思 这个信号处理完了回到哪去呢从哪中断回到哪。举个例子 比如说你这个信号执行到第十行了突然产生信号了那么接下来是不是要处理这个信号呢处理完这个信号接下来是不是又回到10行从这个图上我们可以看得出来信号的优先级 要高于其他动作啊 出现信号要优先处理信号 处理完信号以后呢再去执行刚刚你从中断的位置上再继续往下执行高于普通操作信号有三种状态一个是信号产生这个信号是怎么产生的这个信号是不是得产生啊 你这个程序不close掉他会产生信号吗 sleep 100现在是不是已经执行起来了 是不是你查的时候man 1 是不是你查的命令啊 你不写他从1开始发 man 2 查的是系统调用 或者是系统函数 man 3 查的是c语言的库函数 man 7今天会讲 定时器 alarm每一个进程都有一个唯一的定时器这个定时器有点类似于手机上的闹钟 非法访问内存(段错误)会close掉 除0你的进程会立刻死掉 命令产生kill 未决:产生和递达之间的状态。主要由于阻塞(屏蔽)导致该状态 一个进程收到信号默认会去处理它但是如果这个信号被阻塞了阻塞的意思是不是暂时不让他处理的意思 他就相当于屏蔽掉他了这时候就相当于处于未决状态 这个是后面讲 信号级相关操作的时候会讲这个 递达:递送并且到达进程。 信号已经处理了 就是递达状态 信号的处理方式 信号的处理动作 有三个  直接看手册 man 7 signal 这个里面就能够把这个信号相关的信息传达出来比如说signa1 dispositions 信号的处理方式term是不是终止的意思终止进程 Ign 忽略信号 Core内存非法访问照成的 stop进程暂停 Cont 使进程继续执行 stop 和Cont 他俩是一对 暂厅停止是一对 信号的四要素每一个信号 用四种属性去描述他 一个是信号的名字SIGHUP  大写的宏叫信号的名字 SIGINT 是不是刚刚说过了ctrlc 是不是可以产生这个信号啊 value指的是信号的编号 action 信号的默认处理动作什么叫默认处理动作啊 那么对象如果你的进程不处理他他有一个默认处理动作 后面咱们会讲怎么捕获他 comment 这个信号怎么产生的一个信号描述 被键盘中断其实就是说的ctrlc SIGPIPE 往一个没有读端的管道写数据你把他的管道读端给关掉然后你可以写数据你看看会不会收到这个信号一定会收到这个信号 SIGCHLD重点讲的这个信号Ign 忽略什么情况下才会产生这个信号是不是子进程 停止或者终止 停止相当于暂停的意思stopped 和terminated是不一样的terminated是终止的意思进程彻底死掉了 The signals SIGKILL and SIGSTOP cannot caughtb1ocked, or ignored 不能阻塞 不能忽略 收到这两个信号SIGKILL  SIGSTOP 必须有处理动作这两个处理动作一定是默认动作不能定义只能是默认动作吧 SIGKILL的默认动作是什么呢Kill signal默认是终止的意思Term SIGSTOP stop 是暂停的意思 在这里面信号里面有3种值 这个信号的编号有的是有三种值SIGUSR1 SIGUSR2  在一个系统上只有1个值在linux系统下他是终端这个值其中你不知道这个也没有关系因为你在使用信号的时候呢你不要使用编号你使用宏名就可以了那么宏名你管他是什么不同的系统上他表现的数值不一样对于这个宏是不是都一样的 别的信号用的相对比较少SIGIOT SIGEMT SIGSTKFLT … 你也不用再关注了 很少用它 其实信号的处理动作还有两个是暂停和继续执行大部分都是终止终止是不是才会对你的系统照成的影响最小啊? 你比如说你这个你本来进程被core掉了你如果不知道怎么终止的话他是不是会非法访问其他内存啊有可能给你修改吧这一修改不得了其他程序也会core掉了是不是会照成连锁反应啊 忽略 丢弃不处理的意思相当于就当他没发生 捕捉信号 捕捉是咱们需要注册shell命令函数让他去执行我们自己定义的函数 信号有很强的延时性信号处理是不是要进入 内核啊我们信号是不是需要暂时的阻塞啊那么阻塞 如果说后面呢你不阻塞再写出注册这个信号是能够被处理的从这点来说我们可以知道这个信号是有延时的我们介绍信号集相关函数我给你介绍阻塞这一块你就知道了一开始你不处理他后来呢你又想处理他了然后解除注册这个信号就能够被处理了从这一点来说也能够感觉到这个信号是有延时性的 然后你去不阻塞他的话呢他的这个延时你是感觉不到的因为这个时间十分的短暂这个信号处理的话呢他会进入到内核 咱们前面讲到pcb的时候给大家说过了这个信号集相关的东西是不是都在这个pcb里面在这里面主要指的是阻塞信号集和未决信号集。 信号相关的函数 先给大家讲一个 signal函数 咱们用的比较多的 完成一个信号的注册注册一个用户自定义的函数 言外之意这个信号是要发生的就会去调用信号处理函数 是不是和 这个图这个意思啊这个代码执行到这个位置之后产生的信号是不是就会执行信号处理函数啊 这个函数是用户自己写的用户自己写的函数还得调用signal函数完成注册不然的话人家怎么知道执行哪个函数啊 typedef void (*sighandler t)(int); sighandler_t signal(int signum,sighandler_t handler); signum信号的编号每一个信号是不是都有一个编号啊数字就是编号但是你使用的时候用哪个啊用宏 不要用数字sighandler_t  第二个参数是信号处理函数的函数名 函数名代表函数的首地址就是指针嘛 函数指针那么这个函数指针 指向这个函数呢有一个参数 int类型的那么你说这个int类型是个什么东西 信号的编号 前面给大家讲pipe 讲管道的时候是不是给你说 如果说读端全部关闭了然后你再写管道的话是不是会发生一个会产生信号啊 创建了一个管道pipe 我关闭了写端 后面是读吧我把读端给关闭 让我写 0是读端我把读端关闭了 调用signal注册一个信号处理函数signal在哪调用都行在关闭读端前面调用也行 第一个是信号编号第二个是信号处理函数我主要是想让大家看一下到底我把读端关闭以后然后我再写入管道是不是会产生一个信号 接下来是不是你要写这个sighandler函数了 一个void 类型的 他有一个参数 signo那么咱们打印一下 这个signo到底是不是这个sigpipe信号 sigpipe 是13 打印这个signo是不是13就知道了吧 产生了13信号这个信号是谁产生的内核产生的信号发给当前进程 我把这个代码原理再说一下 代码很简单调用pipe创建一个管道创建管道是不是在内核就有一个缓冲区了读写两端来标识这个缓冲区我们调用signal函数完成SIGPIPE信号的注册第一个参数是信号的编号的个参数是信号的处理函数 也就是说这个信号发生之后 去处理哪个函数的意思 去执行哪个函数举个例子假如说我这个函数执行到 write这个位置了他一写 你如果写完了 这个时候是不是信号产生了 因为他是不是正在往一个没有读端的管道写数据啊内核检测到这个错误了立刻就产生了一个信号那么这个信号呢 产生信号是SIGPIPE信号 而且 我们这个当前进程是不是也注册了这么一个信号啊内核就知道这个信号产生之后去执行这个sighandler函数sighandler函数是内核执行的还是你用户进程执行的是内核执行的其实这个回调函数你想一下 回调函数一般是让你自己写这个函数让别人去执行 回调函数实现是用户进行实现的但是执行不是用户进行执行的对于这个sighandler函数是内核执行的这个函数那么内核是怎么知道执行这个函数了因为你已经告诉他了28行那么这个其实这个注册呢 如果严格的说是这样说 给内核注册一个信号处理函数是给内核注册的那么内核检测到这个信号产生了是不是立刻就会执行这个函数了? 它这个函数打印出来这个signo 13 这个是不是验证了咱们前面的说法吧 给一个没有读端的管道写数据会产生signo信号是不是这样的 信号的特点是必须在某种特定条件下才会产生 信号的产生信号比如说 按键盘命令 函数 软中断 硬件中断 是不是都会产生信号啊 信号的状态 信号有3种状态必达产生状态 未结产生状态 产生状态 信号的四要素 每个信号多有编号 信号的名字那个宏就是名字我们用名字不要用编号 信号的默认处理动作 大部分的信号的默认处理动作是终止  因为只有这个进程终止之后才会对系统产生的  (  )最小 信号是如何产生的是不是后面两个comment啊 action是不是默认冲突  也就是说这个comment是描述的这个信号是如何产生的是不是前面咱们前面讲的这个信号扩展的时候说过了信号是在某种特定条件才会产生吧这个信号虽然说有这么多个但是对于我们来说 有些信号需要我们了解一下但是 这些信号 几个常用到的信号 你大致了解了解因为这些东西用的相对较多你得知道比如说SIGINT 2号编号吧是不是ctrlc产生的 SIGQUIT ctrlz/ 使进程退出 SIGKtLL和 SIGSTOP.是不能被捕获 阻塞忽略的 SIGSEGV 这个信号呢是非法访问内存会产生的信号 端溢出内存溢出等等都会产生信号 SIGUSR1、SIGUSR2 这两个信号是系统留给咱们自己来使用的是用户信号这两个信号 我们自己可以来用其他信号你不要乱发因为它都是在某种特定条件下产生的但是你不能乱用但是这两个信号 SIGUSR1、SIGUSR2  你自己随便用 SIGALRM后面会讲会产生的信号 SIGTERM使进程终止 SIGTERM和SIGKILL有什么区别都是使进程终止SIGKILL这个信号不能被捕获 SIGTERM能够被捕获但是这个信号的默认处理动作是终止那么如果说你捕获之后你可以让他不终止 SIGCHLD重要的一个信号这个信号是子进程退出之后内核会给它的父进程发出一个信号那么他的父进程收到之后回收子进程 这就是父进程回收子进程的一个时机 SIGSTOP使进程暂停 SIGCONT使进程继续执行 信号默认处理动作信号默认处理是5种 信号注册注册由信号产生之后会执行信号的注册函数那个是一个回调函数那个函数实现是用户实现的调用是内核调用的 后面讲信号的处理过程的时候再说 kill函数他对应的系统命令是kill命令 给指定进程发送指定信号那么指定进程是怎么标识是不是进程的pid啊发送指定信号那么这个信号怎么标识啊是不是信号编号啊 所以说你使用这个函数的时候肯定是要有两个参数第一个产生是编号第二个参数是进程 kill命令在使用的时候是不是也是这样kill -9 9是信号编号后面来个pid pid就是指的是进程的pid 这就标识了给哪个进程发送哪个信号 函数原型int kill(pid_t pid, int sig) pid_t这个变量的类型见没见过是不是进程pid啊进程pid就是这个类型 第二个是signo 信号的编号 成功返回0  失败返回-1 pid 0:发送信号给指定的进程。 pid 0: 发送信号给与调用 kill 函数进程属于同一进程组的所有进程。 举例父进程循环创建3个子进程这三个子进程和父进程是不是同一组如果说你要想把这四个进程一次性全部给杀死 函数的pid 参数写0就可以了那么这个0是什么意思呢你要给这个当前进程他自己调用这个kill函数进程 是不是叫单独进程啊给他的一个组发发哪个信号都可以  发个-9就可以了 这样的话一删就可以把这4个进程全部给他杀死是不是相当于杀了一个组啊 pid -1:取|pid|发给对应进程组。 如果pid -1表示 取pid的绝对值发送给对应进程组比如说你这个进程组他的pid 他的组id是100那么你这用的时候用多少写-100就可以了 那么写-100表示给这个组发呢这个东西杀伤面都比较大一般不用 pid -1发送给进程有权限发送的系统中所有进程。 这个杀伤面更大 如果你在root用户里面调用这么一个函数 是不是其他的所有的用户全部都受影响啊因为root用户有最高权限root用户可以给普通用户发送告急信号反过来普通用户能不能给其他用户 或者root用户发送啊 没有权限 这四个里面虽然说了4个但是绝大多数情况下99.9%的情况你只用第一个相对安全假如说 后面的这些参数你都不知道你只知道0的这么一个参数那么你能不能把这四个进程全部杀死来个循环就可以了 每个进程都属于一个进程组进程组是一个或多个进程集合他们相互关联共同完成一个实体任务每个进程组都有一个进程组长默认进程组 ID 与进程组长 ID 相同。 比如说多进程服务一般情况下都是共同协作 完成一个特定任务每一个进程组都有一个组长默认进程组 ID 与进程组长 ID 相同 。 一个父进程创建三个子进程很显然肯定是父进程是组长 写一个简单的程序 kill函数测试 kill 也有头文件 kill自杀 打印这句话看看能不能打印出来如果说没打印出来说明这个进程已经死掉了 父进程能不能杀死子进程啊 可以 子进程能不能杀死父进程 把进程组的概念也说一下 严格的说不是父进程杀死子进程而是说父进程给子进程发送信号kill这个函数其实不是杀死的意思在这是给谁谁谁发送信号的意思 或者子进程杀死父进程 这个是循环创建三个子进程 我先把这个进程组的概念先给你提一句 为什么shellp10 让他不退出便于我们观察 ps -ajx 第一个是父进程pid 这个是  pid 是哪个进程的 pgid是组id sid是会话id 2016是这个kill1进程的父进程 他的父进程应该是-bash啊 2369是他自己的pid 组的话也是2369他自己 他的会话id 2106 是不是bash啊 2369 接下来这三个是不是都是子进程啊这三个子进程很显然 父进程都是2306 子进程自己的pid 各自都不一样  组都是一样的 2369 和pid 2369是一样的 也就是说 这三个子进程 和这一个父进程他们的组id就是父进程的pid 会话id 也是同一会话2106 是不是bash啊 我们这四个进程 当然是包括一个父进程 3个子进程 在一个组当中也在一个会话当中实际上一个会话会可以包含一个或多个组