中跃建设集团网站吗,WordPress怎么两个标题,网站空间在哪买,网络舆情监测系统使用kill -l命令查看信号#xff1a;
信号量和信号确实一点关系没有
信号是操作系统发出的进程与进程之间的通知于中断#xff0c;是进程之间时间异步通知的一种方式 先了解同步通信#xff1a;同步通信是一种比特同步通信技术#xff0c;要求发收双方具有同频同相的同步…使用kill -l命令查看信号
信号量和信号确实一点关系没有
信号是操作系统发出的进程与进程之间的通知于中断是进程之间时间异步通知的一种方式 先了解同步通信同步通信是一种比特同步通信技术要求发收双方具有同频同相的同步时钟信号只需在传送报文的最前面附加特定的同步字符使发收双方建立同步此后便在同步时钟的控制下逐位发送/接收。 优点是效率高缺点是硬件要求高 什么叫异步通信异步通信是指发送方在向接收方发送数据的时候可以有任意的时间间隔没有严格的时序要求而接收方需要一直存在来接收数据 优点是便宜缺点是效率低 信号量是一个计时器表示可用资源的数量
进程产生信号的方式有四种
通过终端按键发出信号
例如你输入ctrl c的时候可以中断进程,ctrl \是离开信号ctrl z是暂停信号
这些信号分别对应了上图的2信号3信号20信号
通过系统调用函数产生信号
kill命令在实现的时候也是调用kill函数实现的kill函数可以给指定进程发送指定的信号 #includesignal.h int killpid_t pid,int signo); 来写一个kill函数的调用:
mykill:
#includestdio.h
#includesignal.h
#includesys/types.h
#includeunistd.h
#includestdlib.h
int main(int argc,char *argv[]){if(argc!3){perror(kill false);return 1;}pid_t pidatoi(argv[2]);int sigatoi(argv[1]);kill(pid,sig);//啊啊啊啊一开始写反参数的顺序了气死了return 0;
}
myprocess.c:
#includestdio.h
#includesignal.h
#includesys/types.h
#includeunistd.h
void handler(int sig){printf(get a sig form myskill,sig%d,sig);
}int main(){signal(2,handler);//signal是个系统调用函数第一个参数是输入的信号是几第二个参数有三种类型//此处的类型为一个函数指针在执行该语句的时候执行一个handler函数这个函数是要自己声明的//格式为int handler(int sig)while(1){printf(a process,pid%d\n,getpid());fflush(stdout);sleep(1);}return 0;
} 除了kill函数还有abort函数使当前进程接收到信号而异常终止 #includestdlib.h void abort(void) 用go也写一个
package mainimport (fmtosos/signalsyscall
)func main() {sigs : make(chan os.Signal, 1)done : make(chan bool, 1)signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) //将sigint和sigterm的信号传给sig//process start//get a sig interrupt,这个interrupt就是syscall.SIGINT返回的信号go func() {sig : -sigs//将信号发送给sigfmt.Println(get a sig, sig)done - true//标为结束}()fmt.Println(process start)-done
}myabort.c:
#includesignal.h
#includesys/types.h
#includeunistd.h
#includestdlib.h
void handler(int sig){printf(get a sig);
}
int main(){signal(3,handler);//捕获信号while(1){sleep(1);abort();//捕获之后就终止进程因为abort就是终止}return 0;
} 那abort()函数收到信号会终止那么是不是我让他捕捉所有的信号就不能终止我的进程了
void catchSig(int signum)
{printf(get a signal:%d,signum);
}
int main()
{for(int sig 1; sig 31; sig) {signal(sig, catchSig);}while(true){sleep(1);}return 0;
} 信号9不能被自动捕捉哦
但是我们还是可以用kill -9 pid来终止该进程 还有raise是给自己当前的进程发送信号
#includestdio.h
#includesignal.h
#includesys/types.h
#includeunistd.h
#includestdlib.h
void handler(int sig){printf(get a sig,sig%d\n,sig);fflush(stdout);
}
int main(){signal(3,handler);while(1){sleep(1);raise(3);//给当前进程发送信号3}return 0;
} 由软件条件产生的信号 上图的信号13是一个管道中由软件产生的信号读端关闭写端一直写入的时候os会直接啥的写端进程怎么杀掉呢通过向目标文件发送SIGPIPE13信号终止目标进程这就叫软件条件
由硬件异常生成的信号
硬件发生异常后以某种方式被检测到并且通知到内核内核再向进程发送适当的信号也是设计到软件条件产生的信号
软件条件和硬件异常的产生的信号的区别软件条件就是操作系统和应用程序内部生成的硬件信号是物理设备外设通过中断机制发送
进程递达阻塞和捕捉
一个信号在发送给一个进程的时候需要三个阶段这个信号我收不收这个信号我要不要写入我写入/或者不写入用不用 表现出来就是一个task_struct下的三个标志位block(要不要阻塞对应前面的这个信号我收不收pending(bit位的位置表示编号不同位置代表不同的信号对应位置的信号写入则置为1否则置为0)例如block 位图的最低一个比特位就表示是否对 1 号信号进行阻塞pending 位图的最低一个比特位就表示是否收到 1 号信号。
bandler这个信号我要不要忽视这个信号我用不用
阻塞和忽略是不同的阻塞是不接收这个信号忽略是接收这个信号写入该信号但是不执行这个信号也就是说信号被阻塞就不能递达递达之后才能选择你能不能忽略
信号递达执行信号的处理动作称为信号递达Delivery)
信号从产生到递达从有信号到执行信号的状态称为信号未决Pending
信号集
能表示多个信号的一种数据类型叫信号集signal set信号集其实就是 sigset_t 类型数据结构
在阻塞信号集下的每个信号的“有效”和“无效”指的是这个信号有没有被阻塞在未决信号集下的有无效是指是否处于未决状态
阻塞信号集也叫信号屏蔽字(Signal Mask)这里的屏蔽的意思阻塞
sigset_t下的每个信号都用每个bit来判定信号是有效还是无效
设置信号集
通过函数设置信号集
#include signal.h
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismemberconst sigset_t *set, int signo);
我们来解释一下这些函数
sigemptyset(),用于清空初始化信号集使其中所有的信号对应的bit清零表示该信号集不包含有效信号
sigfillset(),也是初始化信号集内的信号但是与sigemptyset()的区别是sigfillset()是置位全部置为有效信号
每次使用sigset_t类型的变量之前一定要调用sigemptyset或sigfillset做初始化初始化后就可以调用其他的如sigaddset或sigdelset做添加或删除某种有效信号
这四个函数的返回值都是成功返回0失败返回-1
而sigismember是个bool类型的函数用于判断该信号集是否包含某种信号包含返回1不包含返回0出错返回-1
维护信号集
调用函数sigprocmask()可以读取或更改进程的信号屏蔽字也就是阻塞信号集
#include signal.h
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
// 返回值:若成功则为0,若出错则为-1
若oset是非空指针则读取进程的当前信号屏蔽字通过oset参数传出输出型参数
如果set是非空指针则更改进程的信号屏蔽字参数how指示如何更改
如果oset和set都是非空指针则将原来的信号屏蔽字备份到oset里然后根据how和set来修改信号屏蔽字
若mask是我们当前的信号屏蔽字这是how的可选选项 如果调用 sigprocmask 解除了对当前若干个未决信号的阻塞则在sigprocmask返回前至少将其中一个信号递达。
原理一个信号被阻塞也就是在信号屏蔽字内的时候就处于未决状态当调用过sigprocmask就意味着至少有一个信号得进入递达状态内核至少递送一个信号
读取当前进程的信号集
#include signal.h
sigpending(s);
sigpending 函数可以读取当前进程的未决信号集通过 s 参数传出。调用成功则返回0出错则返回-1。
信号捕捉的过程
信号在内核态返回到用户态进行信号的检测和处理 如果处理信号的函数是用户自定义的函数那么在信号递达的时候调用这个函数称为捕捉信号。 在信号捕捉中一共会涉及到四次状态转换
可重入函数
可重入函数reentrant function是指在多个执行流下能够被同时调用而不会产生冲突或错误的函数。
这种函数能够保证在任意时刻无论被同一个还是不同执行流调用都能正确地完成预期的功能。
如果一个函数符合以下条件之一则是不可重入的: 调用了malloc或free因为malloc也是用全局链表来管理堆的。 调用了标准I/O库函数标准I/O库的很多实现都以不可重入的方式使用全局数据结构。