IntelBook_cn.doc

Similar documents
ebook15-10

第6章 信号量,中断和时间

linux进程间通信

多进程管理副本.key

46 * the current mask in old_mask and block until a signal comes in. 47 */ /* 自动地更换成新的信号屏蔽码, 并等待信号的到来 * * 我们需要对系统调用 (syscall) 做一些处理 我们会从系统调用库接口取得某些信息

上 述 的 描 述 是 在 一 台 计 算 机 上 只 有 一 颗 CPU, 并 且 该 CPU 只 有 一 个 核 心 的 情 形, 在 这 种 环 境 下, 虽 然 系 统 可 以 运 行 多 个 任 务, 但 是 在 某 一 个 时 间 点,CPU 只 能 执 行 一 个 进 程 但 是 如

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Guava学习之Resources

,,.,. :, :,1999. Barry Wilkinson and Michael Allen. Parallel Programming(Techniques and Applications using Networked Workstations and Parallel

Multithreaded Programming Guide.ppt [兼容模式]

威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 號 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

C 1 # include <stdio.h> 2 int main ( void ) { 4 int cases, i; 5 long long a, b; 6 scanf ("%d", & cases ); 7 for (i = 0;i < cases ;i ++) 8 { 9

06?????k?g

提纲 1 2 OS Examples for 3

第 一 节 认 识 自 我 的 意 义 一 个 人 只 有 认 识 自 我, 才 能 够 正 确 地 认 识 到 自 己 的 优 劣 势, 找 出 自 己 的 职 业 亮 点, 为 自 己 的 顺 利 求 职 推 波 助 澜 ; 一 个 人 只 有 认 识 自 我, 才 能 在 求 职 中 保 持

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

PowerPoint Presentation

ebook

帝国CMS下在PHP文件中调用数据库类执行SQL语句实例

chap07.key

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

<4D F736F F D204C696E7578CFB5CDB3B5F7D3C3C1D0B1ED>

团 学 要 闻 我 校 召 开 共 青 团 五 届 九 次 全 委 ( 扩 大 ) 会 议 3 月 17 日, 我 校 共 青 团 五 届 九 次 全 委 ( 扩 大 ) 会 议 在 行 政 办 公 楼 五 楼 会 议 室 举 行, 校 团 委 委 员 各 院 ( 系 ) 团 委 书 记 校 学 生

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

手册 doc

ChinaBI企业会员服务- BI企业


OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

第 1 页共 9 页 文档履历 版本号日期制 / 修订人内容描述 V 正式版本

Microsoft Word - 11.doc

无类继承.key

专题一.ppt

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

36 p->p_osptr->p_ysptr = p->p_ysptr; 37 if (p->p_ysptr) 38 p->p_ysptr->p_osptr = p->p_osptr; 39 else 40 p->p_pptr->p_cptr = p->p_osptr; 41 free_page((

2005 Sun Microsystems, Inc Network Circle, Santa Clara, CA U.S.A. Sun Sun Berkeley BSD UNIX X/Open Company, Ltd. / Sun Sun Microsystems Su

M E M O 內 部 通 讯

M E M O 內 部 通 讯

上海盛瑞电子有限公司

《C语言程序设计》教材习题参考答案

说 : 荀 子 极 偏 驳, 只 一 句 性 恶, 大 本 已 失 5 朱 熹 说 : 荀 扬 不 惟 说 性 不 是, 从 头 到 底 皆 不 识 6 采 取 的 都 是 这 种 理 论 框 架 另 一 种 理 论 框 架 始 于 20 世 纪 前 期, 这 便 是 诸 子 学 研 究 的 框 架

PowerPoint Presentation

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式]

<4D F736F F D E4345C6BDCCA84323B1E0B3CCD2AAB5E3D6AED2BB2E646F63>

Natural Language Processing, Topic Modeling, Neural Text Generation and Ali Xiaomi

Chapter 9: Objects and Classes

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

新・明解C言語入門編『索引』

云数据库 RDS SDK

LETD型LED灯炮规格的更改

CC213

第7章-并行计算.ppt

《C语言程序设计》第2版教材习题参考答案

2013 C 1 #include <stdio.h> 2 int main(void) 3 { 4 int cases, i; 5 long long a, b; 6 scanf("%d", &cases); 7 for (i = 0; i < cases; i++) 8 { 9 scanf("%

11 基于进程的并发编程 2017 年 5 月 3 日 20:22 1. 对于在父 子进程间共享状态信息, 进程有一个非常清晰的模型 : 共享文件表, 但是不共享文件空间 进程有独立的地址空间既是优点也是缺点 : a. ( 优点 ) 一个进程不可能不小心覆盖另一个进程的虚拟存储器 b. ( 缺点 )

<4D F736F F F696E74202D20B8DFBCB6D3C3BBA7BDE7C3E6D3EBB6E0CFDFB3CC2E707074>

Linux-2

untitled

untitled

untitled

C 1


}; "P2VTKNvTAnYNwBrqXbgxRSFQs6FTEhNJ", " " string imagedata; if(0!= read_image("a.jpg",imagedata)) { return -1; } string rsp; ytopen_sdk m_sd

untitled

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式]

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式]

Microsoft PowerPoint - 05-Status-Codes-Chinese.ppt

interfaces which it implements): int read(bytebuffer) throws IOException; int read(bytebuffer[] buffers) throws IOException; int read(bytebuffer[] buf

Microsoft Word - Broker.doc

Generated by Unregistered Batch DOC TO PDF Converter , please register! 浙江大学 C 程序设计及实验 试题卷 学年春季学期考试时间 : 2003 年 6 月 20 日上午 8:3

Symbian培训免费讲座

格式化字符串 Weifeng Sun School of Software, DLUT

TD

ebook15-12

一 登录 crm Mobile 系统 : 输入 ShijiCare 用户名和密码, 登录系统, 如图所示 : 第 2 页共 32 页

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

Natural Language Processing, Topic Modeling, Neural Text Generation and Ali Xiaomi

计算机网络实验说明

fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] -= fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwi

DiffusinMiniLCD

FPGAs in Next Generation Wireless Networks WPChinese

untitled

技 术 文 件

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

第3章.doc

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

Kubenetes 系列列公开课 2 每周四晚 8 点档 1. Kubernetes 初探 2. 上 手 Kubernetes 3. Kubernetes 的资源调度 4. Kubernetes 的运 行行时 5. Kubernetes 的 网络管理理 6. Kubernetes 的存储管理理 7.


378高雄市都市計畫說明書

<B0EAA4E52DB8D1AA522E747066>

INTRODUCTION TO COM.DOC

手说TTS开发指南

Microsoft PowerPoint - 10 模板 Template.pptx

校园之星

概述

Microsoft PowerPoint - os_4.ppt

Microsoft Word - MAN2011A_CH_RTT.doc

操作系统实验指导手册 实验二 2 一 实验目的 1. 掌握进程管理与同步 : 实现 fork exec join 系统调用. 2. 掌握进程调度 : 实现优先级调度. 二 实验内容 运用理论课上学习的 fork exec waitpid / join 等系统调用的工作原理, 在 Nachos 上实现

Transcription:

3.3.3 信号 (Signal) 处理 信号 (signal) 是向进程发送的软件通知, 通知进程有事件发生 引发信号的事件发生时, 信号就被生成 (generate) 了 进程根据信号采取行动时, 信号就被传递 (deliver) 了 信号的寿命 (lifetime) 就是信号的生成和传递之间的时间间隔 已经生成但还未被传递的信号被称为挂起 (pending) 的信号 在信号生成和信号传递之间可能会有相当长的时间 传递信号时, 进程必须在处理器上运行 如果在传递信号时, 进程执行了信号处理程序 (signal handler), 那么进程就捕捉 (catch) 到了这个信号 程序可以使用用户编写的函数名作为参数调用 sigaction 来安装用户自定义的信号处理程序 ; 或者以 SIG_DFL 或 SIG_IGN 作为参数调用 sigaction 函数,SIG_DFL 表示采取默认的动作,SIG_IGN 表示忽略信号, 这两个动作都不是在 捕捉 信号 如果将进程设置为忽略 (ignore) 某个信号, 那么在传递时那个信号就会被丢弃, 不会对进程产生影响 信号生成时所采取的动作取决于那个信号当前使用的信号处理程序和进程信号掩码 (process signal mask) 信号掩码中包含一个当前被阻塞信号(blocked signal) 的列表 阻塞一个信号很容易和忽略一个信号混淆起来 被阻塞的信号不会像被忽略的信号一样被丢弃 如果一个挂起信号被阻塞了, 那么当进程解除了对那个信号的阻塞时, 信号就会被传递出去 程序通过调用 sigprocmask 改变它的进程信号掩码来阻塞一个信号, 而通过调用 sigaction 将信号处理程序设置为 SIG_IGN 来忽略一个信号 注意, 信号最初是在多进程系统中引入, 而本节的重点在于讲述多线程系统中如何处理信号 本节所涉及的函数 数据类型和宏定义都需要使用 signal.h 头文件 3.3.3.1 产生信号 每个信号都有一个以 SIG 开头的符号名 信号的名字都定义在 signal.h 中, 任何一个使用了信号的 C 程序中都要包含这个文件 信号的名字都是某个大于 0 的小整数的宏定义 表 3.10 中描述了必须的 POSIX 信号, 并列出了它们的默认行为 有两个信号 SIGUSR1 和 SIGUSR2 是提供给用户使用的, 没有预先指定的用途 出现某些错误时, 会产生诸如 SIGFPE 或 SIGSEGV 这样的信号, 其它的信号是由 alarm 这样特殊的调用产生的 信号 描述 默认行为 SIGABRT 进程放弃 与实现有关 SIGALRM 报警时钟 为正常终止 SIGBUS 访问了内存对象中的未定义 与实现有关 部分 SIGCHLD 子进程被终止 停止或继续 忽略 SIGCONT 如果进程被停止了, 本信号使 继续 进程继续执行 SIGFPE 算术计算中出现了被零除的 与实现有关 错误 SIGHUP 在控制终端或进程上挂起或 非正常终止

终止 SIGILL 无效的硬件指令 与实现有关 SIGINT 交互终端提示信号 ( 通常是 非正常终止 Ctrl-C) SIGKILL 终止 ( 不能被捕获或忽略 ) 非正常终止 SIGPIPE 向一个没有读程序的管道写 非正常终止 入 SIGQUIT 交互终端终止 : 信息转储 ( 通 与实现有关 常为 Ctrl-L) SIGSEGV 无效的内存引用 与实现有关 SIGSTOP 执行停止 ( 不能被捕捉或忽 停止 略 ) SITTERM 终止 非正常终止 SIGTSTP 终端停止 停止 SIGTTIN 后台进程试图进行读操作 停止 SIGTTOU 后台进程试图进行写操作 停止 SIGURG 在套接字上有高带宽数据 忽略 SIGUSR1 用户定义的信号 1 非正常终止 SIGUSR2 用户定义的信号 2 非正常终止 表 3.10 POSIX 信号 调用 kill 函数可以向指定进程发送指定的信号, 调用 raise 函数可以使进程向自己发送指定的信号, 调用 alarm 函数可以使进程向自己在经过指定的秒数之后发送 SIGALRM 信号 由于这些函数不属于本节的主题, 在此不详细介绍, 感兴趣的读者可以自己查询这些函数的相关资料 3.3.3.2 对信号掩码和信号集进行操作 如前所述, 进程可以通过阻塞信号暂时地阻止信号的传递 在传递之前, 被阻塞的信号不会 影响进程的行为 进程的信号掩码 (signal mask) 给出了一个信号集合, 对哪些信号进行阻 塞需要通过信号掩码进行设置 信号掩码的类型为 sigset_t 信号集由下面的五个函数来操作 每个函数的第一个参数都是一个指向 sigset_t 的指针 sigaddset 负责将 signo 加入信号集, 而 sigdelset 将 signo 从信号集中删除 sigemptyset 函数对一个 sigset_t 对象进行初始化, 使其不包含任何信号 sigfillset 也可用来对一个 sigset_t 对象进行初始化, 使其包含所有的信号 sigismember 负责报告 signo 是否在 sigset_t 中 这五个函数的形式为 : int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigismember(const sigset_t *set, int signo);

对于进程来说, 可以通过调用 sigprocmask 函数来检查或修改它的进程信号掩码, 由于该函 数不属于本节的主题, 在此不详细介绍, 感兴趣的读者请自己查阅相关资料 3.3.3.3 信号的捕捉 忽略和等待 sigaction 函数允许调用程序检查或指定与特定信号相关的动作, 即处理信号的行为, 或忽 略信号 由于该函数不属于本节的主题, 在此不详细介绍, 感兴趣的读者请自己查阅相关资 料 关于等待信号, 信号机制提供了一种不需要忙等 (busywaiting) 的等待事件的机制 忙等是指连续地使用 CPU 来检测事件的发生, 而更有效的方式是将进程或线程挂起直到所等待的事件发生为止, 这样其它的进程或线程就可以更有效地使用 CPU 了 POSIX 中的 pause, sigsuspend 和 sigwait 函数提供了三种机制, 用来挂起进程, 直到信号发生为止 pause 函数将调用线程挂起, 直到传递了一个信号为止, 这个信号的动作或者是执行用户定 义的处理程序, 或者是终止进程 如果信号的动作是终止进程,pause 就不返回 如果信号 被进程捕捉,pause 就会在信号处理程序返回之后返回 它的形式为 : int pause(void); pause 函数总是返回 -1 如果被信号中断,pause 就将 errno 设置为 EINTR pause 函数面临的一个主要问题是, 它将错过在调用之前程序收到的信号 为了解决这个问 题, 程序必须不间断地执行两项操作 解除对信号的阻塞, 并启动 pause 也就是说, 这 两项操作应该是原子的 sigsuspend 函数即用来解决这个问题 它的形式为 : int sigsuspend(const sigset_t *sigmask); sigsuspend 函数用参数 sigmask 指向的信号掩码来阻塞相应的信号, 并将进程或线程挂起, 直到进程或线程捕捉到相应的信号 sigsuspend 函数在信号处理程序返回之后返回, 并将 sigmask 指向的信号掩码设置为调用 sigsuspend 之前的信号阻塞状态 sigsuspend 函数总是返回 -1 如果被信号中断,sigsuspend 就将 errno 设置为 EINTR sigwait 函数的形式为 : int sigwait(const sigset_t *restrict sigmask, int *restrict signo); sigwait 函数会将调用的线程挂起, 直到 sigmask 指定的信号集中的信号被挂起, 然后从挂起的信号集合中删除那个信号 当 sigwait 返回时, 会把从挂起的信号集合中删除的那个信号的信号码存储在 signo 指向的地址中 如果成功,sigwait 返回 0, 如果不成功,sigwait 返回 -1 并设置 errno 要注意的是,sigmask 指定的信号集中的信号必须在 sigwait 调用之前被阻塞, 并且不能被 忽略的, 如果为这些信号指定处理函数, 这些处理函数也不会被调用

3.3.3.4 多线程程序中的信号 进程中的所有线程都共享进程中的信号处理程序, 但每个线程可以有它自己的信号掩码 由于线程的操作可以异步于信号, 所以线程与信号的交互会比较复杂 对于线程而言, 有三种信号的类型, 其中异步信号是指传递给某些解除了对该信号的阻塞的线程的信号, 同步信号是指传递给引发该信号的线程的信号, 定向的信号是指由 pthread_kill 函数发送给指定线程的信号 SIGFPE( 浮点异常 ) 这样的错误信号就是同步于引发它们的线程的, 因为引发这些信号的线程将等待信号处理程序完成之后才能继续执行, 而其它信号因为不与特定的线程相关, 所以它们是异步的 如果有几个线程都解除了对同一个异步信号的阻塞, 当有信号到达时, 线程运行系统就从中挑选一个来处理信号 pthread_kill 函数将指定的信号发送到指定的线程 它的形式为 : int pthread_kill(pthread_t thread, int sig); 如果成功,pthread_kill 就返回 0 如果不成功,pthread_kill 就返回一个非零的错误码 下表列出了 pthread_kill 可能发生的错误和对应得错误码 错误 原因 EINVAL sig 是无效的或不被支持的信号码 ESRCH 没有线程对应于指定的 ID 表 3. 11 pthread_kill 可能发生的错误和对应得错误码 尽管 pthread_kill 将信号发送到指定的线程, 但处理信号的行为可能会影响整个进程 例 如, 将 SIGKILL 信号发送给指定线程, 将使整个进程终止 因为 SIGKILL 信号不能被捕捉, 阻塞或忽略, 而它的行为就是将进程终止 虽然信号处理程序是进程范围的, 但是每个线程可以有它自己不同的信号掩码 线程可以用 pthread_sigmask 函数来检查或设置它的信号掩码, 这个函数是 sigprocmask 在线程化程序中的推广 当进程中有多个线程时, 就不应该使用 sigprocmask 函数了, 但在创建其它线程之前, 也可以被主线程调用, 这样可以初始化子线程的信号掩码, 因为当子线程被创建时将继承父线程的信号掩码 这个函数的形式为 : int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); 参数 how 指定修改信号掩码的方式,how 的值如果为 SIG_SETMASK 会使线程信号掩码被 set 取代, 如果为 SIG_BLOCK 会使线程阻塞 set 中的信号, 如果为 SIG_UNBLOCK 会使线程解除对 set 中的信号的阻塞 set 为指定的信号集, 如果为 NULL, 则不进行修改 oset 保存 pthread_sigmask 调用之前的信号掩码 在多线程的进程中进行信号处理的一种推荐策略是 : 为信号处理使用特定的线程 主线程在 创建线程之前阻塞所有的信号, 这样, 所有的线程都将信号阻塞了 然后, 专门用来处理信 号的线程对那些需要处理的信号执行 sigwait, 这样指定的信号都将被这个信号处理线程处

理 3.3.3.5 多线程程序中应用信号的实例 下面是一个简单的信号应用实例 类似于前面的多线程实例, 主线程在创建子线程之后, 等待子线程运行结束, 然后继续运行 不同之处在于, 主线程没有调用 pthread_join 来等待子线程运行结束, 而是等待子线程发送的信号 子线程则在运行结束前向主线程发送信号, 来通知主线程 这样, 利用信号机制, 实现了线程的同步 代码 3. 6 多线程程序中应用信号的实例 #include <stdio.h> #include <pthread.h> #include <signal.h> void *threadfunc(void *pvoid) { pthread_t* main_tid = (pthread_t*)pvoid; printf("child thread says:hello!world!\n"); pthread_kill(*main_tid, SIGUSR1); } int main() { sigset_t sigs; int sig; pthread_t tid; pthread_t main_tid; sigemptyset(&sigs); sigaddset(&sigs, SIGUSR1); sigprocmask(sig_block, &sigs, NULL); main_tid = pthread_self(); pthread_create(&tid, NULL, &threadfunc, &main_tid); sigwait(&sigs, &sig); printf("main thread says:hello!world!\n"); } return 0;