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

国家外管局网站怎么做收汇电脑设计培训学校推荐

国家外管局网站怎么做收汇,电脑设计培训学校推荐,网站域名设置,惠州网站建设 鑫收发信号思想是 Linux 程序设计特性之一#xff0c;一个信号可以认为是一种软中断#xff0c;通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍#xff0c;从而更好的理解信号编程。 信号概述 遵循 POSIX.1#xff0c;…        收发信号思想是 Linux 程序设计特性之一一个信号可以认为是一种软中断通过用来向进程通知异步事件。 本文讲述的 信号处理内容源自 Linux man。本文主要对各 API 进行详细介绍从而更好的理解信号编程。 信号概述 遵循 POSIX.1特别说明除外 1.描述 Linux 支持 POSIX 可靠信号我们成为标准信号也支持 POSIX 实时信号。 信号处置方法 每个信号都有一个定义如何处理信号的处置方法。 下面列表中 “行为” 列定义了每个信号的默认处置行为 信号默认行为Term默认行为是终止进程Ign默认行为是忽略这个信号Core默认行为是终止进程并转储内核dump coreStop默认行为是停止进程Cont默认行为是在进程停止后继续执行该进程 进程可以通过 sigaction(2) 或者 signal(2) 接口修改信号的处置方法。后者在建立信号处理函数时移植性差一些参考 signal(2) 获得详细信息。通过这些系统调用在信号发生时进程可以选择以下行为处理信号 使用默认行为过略信号使用信号处理函数signal handler捕获信号使用用户自定义的函数 默认情况下信号处理函数是在普通进程栈上调用的不过也可以设置它使用其他可选的栈参考 sigaltstack(2) 查看一些关于如何使用以及这样做有哪些好处的讨论。 信号处置是每个进程的属性在多线程应用中信号处置函数对于所有线程都是一样的。 通过 fork(2) 创建的子进程会复制一份父进程的信号处置方法在 execve(2) 执行的过程中进程想要处理的信号处置方法会被设置为默认值而处置方法为忽略的信号保持不变。 发送信号 下面系统调用和库函数提供了调用者发送信号的相关接口 raise(3) 向调用线程发送一个信号 kill(2) 向指定进程、指定进程组下的所有进程、系统的所有进程发送信号 pidfd_send_signal(2) 向 PID 文件描述符指定的进程发送一个信号 killpg(3) 向指定进程组所有成员发送一个信号 pthread_kill(3) 向调用者所在进程中其他 pthread 线程发送一个信号 tgkill(2) 向指定进程中的特定线程发送一个信号这是用来实现 pthread_kill(3) 的系统调用 sigqueue(3) 向指定进程发送一个福袋数据的实时信号 等待捕捉信号 下面系统调用会暂停当前调用线程直至捕捉到一个信号或者无法处理的信号终止该进程 pause(2) 暂停直至捕捉到一个信号 sigsuspend(2) 临时修改信号屏蔽值并暂停执行直至捕捉到任意未屏蔽的信号 同步接收信号 除了通过信号处理函数异步处理信号我们还可以通过同步接收信号也就是说程序会阻塞运行直至接收到信号同时也是在这一点内核会返回调用者一些关于信号的信息。通常有两种方式实现同步信号接收 sigwaitinfo(2)、sigtimedwait(2)、sigwait(3) 都会阻塞执行直到收到指定集合里的信号发生每个调用都会返回接收到信号的信息。signalfd(2) 会返回一个用于读取关于接收信号的文件描述符每次对文件描述符的 read(2调用都会一直阻塞直到通过 signalfd(2) 指定的信号集合里的任何一个信号发生。read(2) 返回的 buffer 里包含关于该信号的描述结构。 信号屏蔽和等待信号 一个信号是可以被屏蔽的也就是说只有在打开屏蔽后才会得到分发。其实我们上面说的信号发生更确切的说是信号分发到了进程。那么信号在生成和被分发之前的状态我们成为等待pending。 一个进程中的每个线程都有一个独立的信号屏蔽signal mask或者也可以称为掩码它只是了线程当前屏蔽掉的信号集合。线程可以通过 pthread_sigmask(3) 来操作信号掩码在传统的单线程应用中可以通过 sigprocmask(2) 来操作信号掩码。 通过 fork(2) 创建的子进程复制一份父进程的信号掩码信号掩码在整个 execve(2) 过程中会一直保留。 一个信号可以是发给进程的也可以是发给线程的。发给进程的信号通常是由内核产生的而不是由特定硬件异常产生的通常是由类似 kill(2) 或者 sigqueue(3) 产生的。而发给线程的信号可能是因为执行了一些特定机器语言指令导致硬件异常比如非法内存访问的 SIGSEGV 信号或者数学错误的 SIGFPE导致的或者是线程执行了特定接口比如 tgkill(2) 或者 pthread_kill(3)。 发给进程的信号是可以被分发到进程内任何没有屏蔽整个信号的线程的。如果不止一个线程没有屏蔽该信号那么内核会随便选一个线程分发该信号。 线程可以通过 sigpending(2) 接口来获得当前处于等待状态的信号集信号集是一个进程等待信号和线程等待信号的共用体。 通过 fork(2) 创建的进程初始化为控的等待信号集在整个 execve(2) 过程中该等待信号集保持不变。 信号处理函数执行 在每次内核模式到用户模式的切换时也就是一个系统调用返回或者调用一个线程到 CPU 上运行内核都会检查该进程建立信号处理函数的信号的非屏蔽信号的等待状态。如果有这样的信号存在那么就会进行以下几步 1内核会在执行信号处理函数前做一些准备工作 1.1信号从等待信号集合中移除 1.2如果信号处理函数是通过 sigaction(2) 安装并指定了 SA_ONSTACK 标记集线程定义了一个候补信号栈使用 sigaltstack(2)那么内核就会安装这个栈 1.3信号相关的一些上下文片段会被封装到栈上的特定帧里保存的信息包括 a程序计数寄存也就是处理函数退出后主程序要执行的下一条指令 b一些为恢复被打断程序运行的架构相关的寄存器 c线程当前的信号掩码 d线程的备用信号栈设置 如果信号是通过 sigaction(2) SA_SIGINFO 标记安装的那么上述信息是可以通过 ucontex_t 对象获取的这个对象由信号处理函数的第三个参数指定。 2内核在栈上为信号处理函数构建一个栈帧内核设置线程的 PC 为信号处理函数的第一条指令并配置信号处理函数的返回地址到一个称为信号蹦床的用户空间代码片段在 sigreturn(2) 中有描述。 3内核将控制权返还给用户空间这样就会从信号处理函数的开始执行。 4当信号处理函数返回时控制器交给信号蹦床代码。 5信号蹦床调用 sigreturn(2)sigreturn(2) 是一个系统调用用来使用步骤 1 中创建的栈帧来恢复信号发生之前的线程状态。信号掩码和备用信号栈也会在这个过程中得到恢复。在完成 sigreturn(2) 调用后内核将控制权交给用户空间线程会接着从被信号打断的点继续执行。 值得注意的是如果信号处理函数不返回比如通过 siglongjmp(3) 将控制权交给了处理函数外或者处理函数通过 execve(2) 执行了一个程序那么最后的步骤就不会执行。这种情况下程序设计者应该特别注意如果想要恢复在进入信号处理函数时屏蔽掉的信号的话就必须自己恢复这些信号掩码使用 sigprocmask(2)。注意siglongjmp(3) 可能恢复信号掩码但是这个要依赖于 sigsetjmp(3) 的 savesigs 值。 从内核的角度来看执行信号处理函数和执行其他任何用户空间代码没有什么区别也就是说内核并不会记录线程当前是否在执行信号处理函数。所有的状态都被保存到了用户空间寄存器和用户空间栈里了所以信号处理函数的嵌套深度完全取决于用户栈大小以及合理的软件设计。 标准信号 Linux 支持的标准信号入下表所示。表中第二列标明了信号出现的规范“P1990” 表示信号是在原先的 POSIX.1-1990 标准中描述的“P2001” 表示信号是在 SUSv2 和 POSIX.1-2001 中添加的。 信号标准行为备注SIGABRTP1990Coreabort(3) 的终止信号SIGALRMP1990Termalarm(2) 的定时器信号SIGBUSP2001Core总线错误错误内存访问SIGCHLDP1990Ign子进程停止或者终止了SIGCLD-Ign同 SIGCHLDSIGCONTP1990Cont如果停止了就继续执行SIGEMT-Term模拟器陷入SIGFPEP1990Core浮点异常SIGHUPP1990Term控制终端上检测到挂机或者控制进程死掉了SIGILLP1990Core非法指令SIGINFO-同 SIGPWRSIGINTP1990Term键盘中断SIGIO-TermI/O 现在可用4.2 BSDSIGIOT-CoreIOT 陷入同 SIGABRTSIGKILLP1990Term杀死信号SIGLOST-Term文件锁丢失不用了SIGPIPEP1990Term破坏的管道写一个没有读者的管道参考 pipe(7)SIGPOLLP2001Term可查询事件Sys V同 SIGIOSIGPROFP2001Term分析定时器超时SIGPWR-Term电源失效System VSIGQUITP1990Core键盘上的退出SIGSEGVP1990Core无效的内存引用SIGSTKFLT-Term协处理器栈错误不用了SIGSTOPP1990Stop停止进程SIGTSTPP1990Stop终端输入的停止信号SIGSYSP2001Core非法的系统调用SVr4参考 seccomp()SIGTERMP1990Term终止信号SIGTRAPP2001Core追踪/断电 陷入SIGTTINP1990Stop后台进程终端输入SIGTTOUP1990Stop后台进程终端输出SIGUNUSED-Core同 SIGSYSSIGURGP2001Ign套接字上的紧急事件4.2 BSDSIGUSR1P1990Term用户定义的信号 1SIGUSR2P1990Term用户定义的信号 2SIGVTALRMP2001Term虚拟定时器时钟4.2 BSDSIGXCPUP2001Core超过 CPU 时间限制参考 setrlimit(2)SIGXFSZP2001 Core 文件大小超过限制4.2 BSD参考 setrlimit(2)SIGWINCH-Ign窗口大小重设信号4.3 BSDSun SIGKILL 和 SIGSTOP 不能被捕捉或者忽略。 Linux 2.2 前SIGSYS/SIGXCPU/SIGXFSZ除了 SPARC 和 MIPS 架构以及 SIGBUS  的默认行为是终止进程并没有内核转储。在一些 UNIX 的系统上SIGXCPU 和 SIGXFSZ 的默认行为也是不转储的终止。Linux 2.4 遵循 POSIX.1-2001 对这些信号的要求会终止进程并进行内核转储。 SIGEMT 并没有在 POSIX.1-2001 中描述但是至少出现在了大多数 UNIX 系统中并且其默认行为是终止进程并内核转储。 SIGPWR 也没有在 POSIX.1-2001 中描述它在起源的一些 UNIX 系统中的默认行为是忽略。 SIGIO 也一样在一些 UNIX 系统上的默认行为是忽略。 标准信号的排队和分发语义 如果多个标准信号正在等待某个进程那么信号的顺序并没有指定。 标准信号没有排队如果一个标准信号的多个实例在信号屏蔽期间到达那么只有一个信号会被设置为等待状态信号只能在其取消屏蔽后会分发给进程。如果一个信号已经在等待和这个信号关联的 siginfo_t 结构参考 sigaction(2)并不会被后面的同一信号的其他实例覆盖。因此进程会接收到第一个达到的信号实例。 标准信号编码 下表列出了各个标准信号的号码。在表中我们可以看出一些信号在不同架构上的号码是不一样的。- 表示对应架构上没有该信号。 信号x86/ARM 以及其他大多数Alpha/SPARCMIPSPARISC备注SIGHUP1111SIGINT2222SIGQUIT3333SIGILL4444SIGTRAP5555SIGABRT6666SIGIOT66        66SIGBUS7101010SIGEMT-77-SIGFPE8889SIGKILL9999SIGUSR110301616SIGSEGV11111111SIGUSR212311717SIGPIPE13131313SIGALRM14141414SIGTERM15151515SIGSTKFLT16---SIGCHLD17201818SIGCLD--18-SIGCONT18192526SIGSTOP19172324SIGTSTP20182425SIGTTIN21212627SIGTTOU22222728SIGURG23162129SIGXCPU24243012SIGXFSZ25253130SIGVTVLRM26262820SIGPROF27272921SIGWINCH28282023SIGIO29232222SIGPOLLSIGPWR3029/-1919SIGINFO-29/---SIGLOST----SIGSYS31121231SIGUNUSED31--31 注意 如果有定义那么 SIGUNUSED 和 SIGSYS 含义相同。但是 glibc 2.26 后不管是什么架构上都没有 SIGUNUSED 定义了。Alpha 上 29 号信号是 SIGINFO/SIGPWR含义相同而在 SPARC 上是 SIGLOST 信号。 实时信号 从 Linux 2.2 开始Linux 开始支持 POSIX.1b 实时扩展定义的实时信号目前包含在 POSIX.1-2001 中。支持的实时信号范围由宏 SIGRTMIN 和 SIGRTMAX 定义POSIX.1-2001 要求至少支持 _POSIX_RTSIG_MAX(8) 个实时信号。 Linux 内核支持 33 个不同的实时信号号码是从 32 到 64。然而glibc 的 POSIX 线程使用了 2个对于 NPTL或者 3 个对于 LinuxThreads实时信号参考 pthreads(7)所以调整 SIGRTMIN 为 34 或者 35。正因为实时信号的范围随着 glibc 多线程的实现不同而不同这个在运行时会根据内核和 glibc 而定并且事实上也会根据不同 UNIX 系统不同而不同所以程序不应该使用硬编码值指定实时信号而应该使用 SIGMINn 这种形式来引用实时信号并且需要在运行时检查其是否超过了 SIGRTMAX。 和标准信号不同实时信号没有预定义的含义即整个实时信号集都可以被应用使用。 实时信号的默认处理行为是终止接收进程。 实时信号通过以下方式来区分 实时信号的多个实例可以排队这个和标准信号完全相反如果信号由 sigqueque(3) 发送可以附带一个这个数值可以是整数或者指针。接收进程通过sigaction(2) 的 SA_SIGINFO 来建立该信号的处理函数然后就可以通过处理函数第二个参数的 siginfo_t 结构的 si_value 来获得这个数值。并且可以通过结构的 si_pid 和 si_uid 可以获得发送信号进程的进程 ID 和用户 ID。实时信号的分发的顺序是能够得到保证的。同一个类型实时信号的多个实例会按照它们实际的发送顺序分发。多个信号发送到同一个进程那么会从号码最小的信号依次分发即号码越小优先级越高。相反多个标准信号处于等待状态先分发谁是没有定义的。 如果一个进程有标准信号和实时信号一起处在等待状态那么 POSIX 并没有指定应该先发送谁。Linux 以及很多其他实现会优先标准信号。 根据 POSIX 规定系统实现应该最少支持 _POSIX_SIGQUEQUE_MAX (32) 个实时信号等待然而 Linux 却采用了不同的方式。Linux 2.6.7 之前只暴漏了对所有进程总共实时信号数的系统级限制这个限制可以通过需要特权/proc/sys/kernel/rtsig-max 文件查看或者修改。可以通过 /proce/sys/kernel/rtsig-nr 查看当前有多少个实时信号正在等待处理。在 Linux 2.6.8/proc 接口被 RLIMIT_SIGPENDING 资源限制取代这是一个每个用户下排队信号的限制可以参考 setrlimit(2)。 实时信号要求信号集结构sigset_t的长度从 32位变为 64 位。所以各个系统调用被新的系统调用取代下面是接口的对照 Linux 2.0 and earlier Linux 2.2 and latersigaction(2) rt_sigaction(2)sigpending(2) rt_sigpending(2)sigprocmask(2) rt_sigprocmask(2)sigreturn(2) rt_sigreturn(2)sigsuspend(2) rt_sigsuspend(2)sigtimedwait(2) rt_sigtimedwait(2) 信号处理函数打断系统调用和库函数调用 如果在系统调用或者函数调用过程中调用信号处理函数那么 系统调用会在信号处理函数返回后自动重启或者调用失败并返回 EINTR 至于采用哪种行为主要取决于具体的接口以及建立信号处理函数时是否使用了 SA_RESTART 标记参考 sigaction(2)。具体行为会随着不同的 UNIX 而不同下面主要描述 Linux 平台上的相关细节。 如果如下接口中的一个阻塞调用被信号处理函数自动打断那么如果使用了 SA_RESTART 标记那么调用会在处理函数返回后自动重启或者会返回 EINTR 错误 慢速设备上的 read(2)/readv(2)/write(2)/writev(2)/ioctl(2) 调用。慢速设备指的是 I/O 调用可能会无限期阻塞的设备比如终端、管道以及套接字。如果这些慢速设备上的 I/O 调用在被打断时已经传输了一些数据那么调用会返回成功状态通常情况下时传输的字节数。注意根据这个定义本地磁盘不是慢速设备磁盘上的 I/O 操作不会被信号打断。open(2)如果它可能阻塞比如当打开一个 FIFO参考 fifo(7)wait(2)/wait3(2)/wait4(2)/waitid(2)/waipid(2)套接字接口accept(2)/connect(2)/recv(2)/recvfrom(2)/recvmmsg(2)/recvmsg(2)/send(2)/sendto(2)/sendmsg(2)除非套接字设置了超时下面会提到文件锁定接口flock(2) 以及 fcntl(2) 的 F_SETLKW/F_OFD_SETLKW 操作POSIX 消息队列接口mq_receive(3)/mq_timedreceive(3)/mq_send(3)/mq_timedsend(3)futex(2) FUTEX_WAITLinux 2.6.22 后之前总是会返回 EINTRgetrandom(2)pthread_mutex_lock(3)/pthread_cond_wait 以及相关 APIsfutex(2) FUTEX_WAIT_BITSETPOSIX 信号量语义接口wem_wait(3)/sem_timedwait(3)Linux 2.6.22 后之前会失败返回 EINTR从 inotify(7) 文件描述符的 read(2)从 Linux 3.8 后之前会返回 EINTR 下面接口在被信号处理函数打断时不会重启无论是否设置 SA_RESTART 标记会返回 EINTR 错误 使用 setsockopt(2) 设置了超时SO_RCVTIMEO的输入套接字接口accept(2)/recv(2)/recvfrom(2)/recvmmsg(2)(同时有非空 timeout 参数以及 recvmsg(2)使用 setsockopt(2) 设置了超时SO_RCVTIMEO的输出套接字接口connect(2)/send(2)/sendto(2)/sendmsg(2)等待信号的接口pause(2)/sigsuspend(2)/sigtimedwait(2)/sigwaitinfo(2)文件描述符多路复用接口epoll_wait(2)/epoll_pwait(2)/poll(2)/select(2)/pselect(2)System V IPC 接口msgrcv(2)/msgsnd(2)/semop(2)/semtimedop(2)睡眠接口clock_nanosleep(2)/nanosleep(2)/usleep(3)io_getevents(2) usleep(3) 在被信号处理函数打断时不会重启会成功返回睡眠剩余时间的秒数。 在一些情况下sseccomp(2) 用户空间通知特性会导致通过 SA_RESTART 配置不会重启的系统调用重启具体可以参考 seccomp_unotify(2)。 停止信号打断系统调用和库函数调用 在 Linux 上即使没有信号处理函数一些阻塞接口也可能在收到停止信号停止在收到 SIGCONT 信号恢复时返回  EINTR 错误。这个行为并没有受到 POSIX.1 的限制并不会在其他系统上发生。 Linux 上会显示出这种行为的接口有 使用 setsockopt(2) 设置了超时SO_RCVTIMEO的输入套接字接口accept(2)/recv(2)/recvfrom(2)/recvmmsg(2)(同时有非空 timeout 参数以及 recvmsg(2)使用 setsockopt(2) 设置了超时SO_RCVTIMEO的输出套接字接口connect(2)/send(2)/sendto(2)/sendmsg(2)epoll_wait(2)/epoll_pwait(2)semop(2)/semtimedop(2)sigtimedwait(2)/gitwaitinfo(2)Linux 3.7 前从 inotify(7) 文件描述符读取的 read(2)Linux 2.6.21 前 futex(2) FUTEX_WAIT/sem_timedwait(3)/sem_wait(3)Linux 2.6.8 前 msgrcv(2)/msgsnd(2)Linux 2.4 前 nanosleep(2) 2.注意 对于安全的异步信号函数可以参考 sigal-safety(7)。 /proc/pid/task/tid/status 文件包含了一些用于显示一个线程正处于阻塞SigBlk、捕获SigCgt或者忽略SigIgn的字段。进程中所有线程的阻塞和忽略信号相同。其他字段展示了发给线程SigPnd或者进程ShdPnd的等待信号。/proc/pid/status 展示了关于主线程的信息。参考 proc(5) 获得详细信息。 3.BUGS 一共有 6 中关于硬件异常的信号SIGBUS/SIGEMT/SIGFPE/SIGILL/SIGSEGV/SIGTRAP。至于这些信号哪些会真的分发文档中并没有给出描述并且也并不总是有效。 比如一个架构非法地址访问可能导致 SIGSEGV但是在其他架构上可能会导致 SIGBUS反过来也是一样。 再比如使用 x86 的 int 指令携带了禁止参数除了 3 和 128 的任意数会导致 SIGSEGV尽管这时发送 SIGILL 会更合适因为它是在向内核报告禁止操作。    4.例程 下面是一个 sigaction 的信号处理例程。 #include signal.h#include stdio.h#include stdlib.h#include unistd.hvoidhandler(int signo, siginfo_t *info, void *context){struct sigaction oldact;if (sigaction(SIGSEGV, NULL, oldact) -1|| (oldact.sa_flags SA_UNSUPPORTED)|| !(oldact.sa_flags SA_EXPOSE_TAGBITS)){_exit(EXIT_FAILURE);}_exit(EXIT_SUCCESS);}intmain(void){struct sigaction act { 0 };act.sa_flags SA_SIGINFO | SA_UNSUPPORTED | SA_EXPOSE_TAGBITS;act.sa_sigaction handler;if (sigaction(SIGSEGV, act, NULL) -1) {perror(sigaction);exit(EXIT_FAILURE);}raise(SIGSEGV);}
http://www.ho-use.cn/article/10820789.html

相关文章:

  • 河南商务学校网站建设外贸企业网站源码下载
  • 网站建设明细报价vs2013网站开发教程
  • 手机网站根目录河南建筑网站
  • 上海网站优化上网站建设规划书3000字
  • 做爰 网站贵阳城乡和住房建设厅网站
  • 菏泽网站建设服务wordpress调用媒体图片不同尺寸
  • 男做女爱网站做网站和自媒体哪个好
  • 用vs2010做免费网站模板下载地址网站移动端是什么问题吗
  • 金麦建站官网wordpress seo模板
  • 广西网站建设策划昭阳区住房和城乡建设管理局网站
  • 网站开发文档范例微网站建设包含哪些内容
  • 广元市建设银行网站c2c代表网站
  • 广州机械网站建设外包北京定制网站价格
  • 网站广告怎么放如何优化关键词排名到首页
  • 如何创建博客网站莱芜一中贴吧
  • 网站建设系统 开源商城版网站制作
  • 算卦网站开发网站开发飞沐
  • 无锡企业网站的建设电力公司在哪个网站做推广最好
  • 赣县城乡规划建设局网站wordpress菜单.html
  • wordpress全站模板外贸营销俱乐部
  • 怎么才能提高网站点击量 免费wordpress get_category_parents
  • 花都五屏网站建设php做网站多少钱
  • 网站手机端做app开发公司网站开发 建设
  • 昆明公司网站开发工作室怎么开
  • 网站制作网站建设单位东营网站建设服务电话
  • 个人网站建设论文绪论常州网站建设软件
  • 北京电商网站开发平台网站排名易下拉排名
  • 如何调整网站板块位置济南正规网站制作品牌
  • 推广网站哪家做的好福州网站制作培训
  • 人工智能的网站python 可以做网站吗