c语言多进程多线程编程.pdf_第1页
c语言多进程多线程编程.pdf_第2页
c语言多进程多线程编程.pdf_第3页
c语言多进程多线程编程.pdf_第4页
c语言多进程多线程编程.pdf_第5页
已阅读5页,还剩62页未读 继续免费阅读

c语言多进程多线程编程.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C 语言多进程编程 一一 多进程程序的特点多进程程序的特点 进程进程是一个具有独立功能的程序关于某个数据集合的一次可以并发执行的运行活动 是处 于活动状态的计算机程序 进程作为构成系统的基本细胞 不仅是系统内部独立运行的实体 而且是独立竞争资源的基本实体 进程进程是资源管理的最小单位 线程线程是程序执行的最小单位 进程管理着资源 比 如 cpu 内存 文件等等 而将线程分配到某个 cpu 上执行 在操作系统设计 上 从进程演化出线程 最主要的目的就是更好的支持多处理器系统和减小上下 文切换开销 进程的状态进程的状态 系统为了充分的利用资源 对进程区分了不同的状态 将进程分为新 建 运行 阻塞 就绪和完成五个状态 新建新建 表示进程正在被创建 运行运行 是进程正在运行 阻塞阻塞 是进程正在等待某一个事件发生 就绪就绪 是表示系统正在等待 CPU 来执行命令 完成完成 表示进程已经结束了系统正在回收资源 由于 UNIX 系统是分时多用户系统 CPU 按时间片分配给各个用户使用 而在实质上应 该说 CPU 按时间片分配给各个进程使用 每个进程都有自己的运行环境以使得在 CPU 做进 程切换时不会 忘记 该进程已计算了一半的 半成品 以 DOS 的概念来说 进程的切换都进程的切换都 是一次是一次 DOS DOS 中断中断 处理过程处理过程 包括三个层次包括三个层次 1 用户数据的保存 包括正文段 TEXT 数据段 DATA BSS 栈段 STACK 共享内 存段 SHARED MEMORY 的保存 2 寄存器数据的保存 包括 PC program counter 指向下一条要执行的指 令的地址 PSW processor status word 处理机状态字 SP stack pointer 栈指针 PCBP pointer of process control block 进程控制块指针 FP frame pointer 指向栈中一个函数的 local 变量的首地址 AP augument pointer 指向栈中函数调用的实参位置 ISP interrupt stack pointer 中断栈指针 以及其他的通用寄存器等 3 系统层次的保存 包括 proc u 虚拟存储空间管理表格 中断处理栈 以便于该进程再一次得到 CPU 时 间片时能正常运行 既然系统已经处理好所有这些中断处理的过程 我们做程序 还有什么要担心 的呢 我们尽可以使用系统提供的多进程的特点 让几个程序精 诚合作 简单而又高效地把结果给它搞出来 另外 UNIX 系统本身也是用 C 语言写的多进程程序 多进程编程是 UNIX 的特点 当我们 熟悉了多进程 将会对 UNIX 系统机制有一个较深的认识 首先我介绍一下多进程程序的首先我介绍一下多进程程序的 一些突出的特点一些突出的特点 1 1 并行化并行化 一件复杂的事件是可以分解成若干个简单事件来解决的 这在程序员的大脑中早就形 成了这种概念 首先将问题分解成一个个小问题 将小问题再细分 最后在一个合适的规模 上做成一个函数 在软件工程中也是这么说的 如果我们以图的方式来思考 一些小问题的 计算是可以互不干扰的 可以同时处理 而在关键点则需要统一在一个地方来处理 这样程 序的运行就是并行的 至少从人的时间观念上来说是这样的 而每个小问题的计算又是较简 单的 1 2 简单有序简单有序 这样的程序对程序员来说不亚于管理一班人 程序员为每个进程设计好相应的功能 并 通过一定的通讯机制将它们有机地结合在一起 对每个进程的设计是简单的 只在总控部分 小心应付 其实也是蛮简单的 就可完成整个程序的施工 1 3 互不干扰互不干扰 这个特点是操作系统的特点 各个进程是独立的 不会串位 1 4 事务化事务化 比如在一个数据电话查询系统中 将程序设计成一个进程只处理一次查询即可 即完成 一个事务 当电话查询开始时 产生这样一个进程对付这次查询 另一个电话进来时 主控 程序又产生一个这样的进程对付 每个进程完成查询任务后消失 这样的编程多简单 只要 做一次查询的程序就可以了 二二 常用的多进程编程的系统调用常用的多进程编程的系统调用 2 1 fork 创建一个新的进程创建一个新的进程 功能 创建一个新的进程 语法 include include include include pid t fork pid t fork 说明 本系统调用产生一个新的进程 叫子进程 是调用进程的一个复制品 调用进程叫父进 程 子进程继承了父进程的几乎所有的属性 进程 代码段 程序代码 堆栈段 局部变量 函数返回地址 函数参数 数据段 全局变量 常数等 在 Linux 系统中 系统调用 fork 后 内核为完成系统调用 fork 要进行几步操作 第一步 为新进程在进程表中分配一个表项 系统对一个普通用户可以同时运行的进 程数是有限制的 对超级用户没有该限制 但不能超过进程表的最大表项的 数目 第二步 给子进程一个唯一的进程标识号 PID 该进程标识号其实就是该表项在进 程表中的索引号 第三步 复制一个父进程的进程表项的副本给子进程 内核初始化子进程的进程表项 时 是从父进程处拷贝的 所以子进程拥有与父进程一样的 uid 当前目录 当前根 用户文件描述符表等 第四步 把与父进程相连的文件表和索引节点表的引用数加 1 这些文件自动地与该子 进程相连 第五步 内核为子进程创建用户级上下文 内核为子进程的代码段分配内存 并复制 父进程的区内容 生成的是进程的静态部分 第六步 生成进程的动态部分 然后对父进程返回子进程的 pid 对子进程返回 0 从父进程拷贝的内容主要有 用户标识符 包括实际用户号 real 和有效用户号 effective 环境变量 打开的文件描述符 套接字描述符 信号处理设置 堆栈 目录 进程组标志 process ID 会晤组标志 session ID 正文 子进程特有内容 进程号 父进程号 进程执行时间 未处理的信号被处理为空 不继承异步的输入输出操作 简述简述 fork fork 调用成功时 分别返回两个整数 对父进程返回 0 的整数 对子进程返回 0 函数执行过程 内核在系统进程表中 创建一个新条目 复制父进程内容 已打开的文件描述符 堆栈 正文等 修改两者的堆栈 给父进程返回子进程号 给子进程返回 0 父进程知道每个子进程 的标志号 而子进程可根据需要调用 getppid 来获得父进程的标志号 例子 pid t fork void pid t fork void include pid t pid if pid fork 0 子进程代码 exit 0 else if pid 0 父进程代码 exit 0 else printf Error exit 1 2 2 system 子进程执行指定的命令子进程执行指定的命令 功能 产生一个新的进程 子进程执行指定的命令 语法 include include include include int system string int system string char string char string 说明 本调用将参数 string 传递给一个命令解释器 一般为 sh 执行 即 string 被解释为一条命 令 由 sh 执行该命令 若参数 string 为一个空指针则为检查命令解释器是否存在 该命令可以同命令行命令相同形式 但由于命令做为一个参数放在系统调用中 应注意 编译时对特殊意义字符的处理 命令的查找是按 PATH 环境变量的定义的 命令所生成的后 果一般不会对父进程造成影响 返回值 当参数为空指针时 只有当命令解释器有效时返回值为非零 若参数不为空指 针 返回值为该命令的返回状态 同 waitpid 的返回值 命令无效或语法错误则返回非零值 所执行的命令被终止 其他情况则返回 1 例子 char command 81 int i for i 1 i 8 i sprintf command ps t tty 02i i system command 应用程序 fork 父进程 子进程 1 子进程 2 2 3 exec 执行一个文件执行一个文件 功能 执行一个文件 语法 include int execve const char path char const argv char const envp int execve const char path char const argv char const envp int execl const char path char arg int execl const char path char arg int execp conint execp const char file char arg st char file char arg int execle const char path const char argv char const envp int execle const char path const char argv char const envp int execv const char path char const arg int execv const char path char const arg int execvp const char file char const arg int execvp const char file char const arg 说明 exec 函数族的作用是根据指定的文件名找到可执行文件 并用它来取代调用进程的内 容 换句话说 就是在调用进程内部执行一个可执行文件 其中只有 execve 是真正意义上的系统调用 其它都是在此基础上经过包装的库函数 与一般情况不同 exec 函数族的函数执行成功后不会返回 因为调用进程的实体 包 括代码段 数据段和堆栈等都已经被新的内容取代 只留下进程 ID 等一些表面上的信息仍 保持原样 颇有些神似 三十六计 中的 金蝉脱壳 看上去还是旧的躯壳 却已经注入了新 的灵魂 只有调用失败了 它们才会返回一个 1 从原程序的调用点接着往下执行 fork 和 exec 这两个函数 前者用于并行执行 父 子进程执行相同正文中的不同 部分 后者用于调用其他进程 父 子进程执行不同的正文 调用前 一般应为子进程创造 一个干净的环境 fork 以后 父 子进程共享代码段 并只重新创建数据有改变的页 段页式管理 exec 以后 建立新的代码段 用被调用程序的内容填充 前者的子进程执行后续的公共代码 后者的子进程不执行后续的公共代码 父 子进程以及各个子进程执行的顺序不定 例子 printf now this process will be ps command n execl bin ps ps ef NULL 2 4 popen 初始化从初始化从 到一个进程的管道到一个进程的管道 功能 初始化从 到一个进程的管道 语法 include include FILE popen command type FILE popen command type char command type char command type 说明 本系统调用在调用进程和被执行命令间创建一个管道 参数 command 做为被执行的命令行 type 做为 I O 模式 r 为从被 执行命令读 w 为向被执行命令写 返回一个标准流指针 做为管 道描述符 向被执行命令读或写数据 做为被执行命令的 STDIN 或 STDOUT 该系统调用可以用来在程序中调用系统命令 并取得命令 的输出信息或者向命令输入信息 返回值 不成功则返回 NULL 成功则返回管道的文件指针 2 5 pclose 关闭到一个进程的管道关闭到一个进程的管道 功能 关闭到一个进程的管道 语法 include include int pclose strm int pclose strm FILE strm FILE strm 说明 本系统调用用于关闭由 popen 打开的管道 并会等待由 popen 激活的命令执行结束后 关闭管道后读取命令返回码 返回值 若关闭的文件描述符不是由 popen 打开的 则返回 1 例子 printf now this process will call popen system call n FILE fd if fd popen ps ef r NULL printf call popen failed n return else char str 80 while fgets str 80 fd NULL printf s n str pclose fd 2 6 wait 等待一个子进程返回并修改状态等待一个子进程返回并修改状态 功能 等待一个子进程返回并修改状态 语法 include include include include pid t wait stat loc pid t wait stat loc int stat loc int stat loc 说明 允许调用进程取得子进程的状态信息 调用进程将会挂起直到其 一个子进程终止 返回值 等待到一个子进程返回时 返回值为该子进程号 否则返回值为 1 同时 stat loc 返回子进程的返回值 例子 父进程 if fork 0 wait int 0 父进程等待子进程的返回 else 子进程处理过程 exit 0 2 7 waitpid 等待指定进程号的子进程的返回并修改状等待指定进程号的子进程的返回并修改状 态态 功能 等待指定进程号的子进程的返回并修改状态 语法 include include include include pid t waitpid pid stat loc optionspid t waitpid pid stat loc options pid t pid pid t pid int stat loc options int stat loc options 说明 当 pid 等于 1 options 等于 0 时 该系统调用等同于 wait 否则该 系统调用的行为由参数 pid 和 options 决定 pid 指定了一组父进程要求知道其状态的子进程 1 要求知道任何一个子进程的返回状态 0 要求知道进程号为 pid 值的子进程的状态 0 waitpid pid 父进程等待进程号为 pid 的子进程的返回 else 子进程的处理过程 exit 1 父进程 printf stat loc is d n stat loc 字符串 stat loc is 1 将被打印出来 2 8 setpgrp 设置进程组号和会话号设置进程组号和会话号 功能 设置进程组号和会话号 语法 include include pid t setpgrp pid t setpgrp 说明 若调用进程不是会话首进程 将进程组号和会话号都设置为与它 的进程号相等 并释放调用进程的控制终端 返回值 调用成功后 返回新的进程组号 例子 父进程处理 if fork 0 父进程处理 else setpgrp 子进程的进程组号已修改成与它的进程号相同 exit 0 2 9 exit 终止进程终止进程 功能 终止进程 语法 include include void exit status void exit status int status int status 说明 调用进程被该系统调用终止 引起附加的处理在进程被终止前全 部结束 返回值 无 2 10 signal 信号管理功能信号管理功能 功能 信号管理功能 语法 include include void signal sivoid signal sig disp int g disp int int sig int sig void disp int void disp int void sigset sig disp int void sigset sig disp int int sig int sig void disp int void disp int int sighold sig int sighold sig int sig int sig int sigrelse sig int sigrelse sig int sig int sig int sigignore sig int sigignore sig int sig int sig int sigpause sig int sigpause sig int sig int sig 说明 这些系统调用提供了应用程序对指定信号的简单的信号处理 signal 和 sigset 用于修改信号定位 参数 sig 指定信号 除了 SIGKILL 和 SIGSTOP 这两种信号由系统处理 用户程序不能捕捉到 disp 指定新的信号定位 即新的信号处理函数指针 可以为 SIG IGN SIG DFL 或信号句柄地址 若使用 signal disp 是信号句柄地址 sig 不能为 SIGILL SIGTRAP 或 SIGPWR 收到该信号时 系统首先将重置 sig 的信号句柄为 SIG DFL 然后执行信号句柄 若使用 sigset disp 是信号句柄地址 该信号时 系统首先将该 信号加入调用进程的信号掩码中 然后执行信号句柄 当信号句柄 运行结束 后 系统将恢复调用进程的信号掩码为信号收到前的状态 另外 使用 sigset 时 disp 为 SIG HOLD 则该信号将会加入调用进程的 信号掩码中而信号的定位不变 sighold 将信号加入调用进程的信号掩码中 sigrelse 将信号从调用进程的信号掩码中删除 sigignore 将信号的定位设置为 SIG IGN sigpause 将信号从调用进程的信号掩码中删除 同时挂起调用 进程直到收到信号 若信号 SIGCHLD 的信号定位为 SIG IGN 则调用进程的子进程在终 止时不会变成僵死进程 调用进程也不用等待子进程返回并做相 应处理 返回值 调用成功则 signal 返回最近调用 signal 设置的 disp 的值 否则返回 SIG ERR 例子一 设置用户自己的信号中断处理函数 以 SIGINT 信号为例 int flag 0 void myself flag 1 printf get signal SIGINT n 若要重新设置 SIGINT 信号中断处理函数为本函数则执行以 下步骤 void a a myself signal SIGINT a flag 2 main while 1 sleep 2000 等待中断信号 if flag 1 printf skip system call sleep n exit 0 if flag 2 printf skip system call sleep n printf waiting for next signal n 2 11 kill 向一个或一组进程发送一个信号向一个或一组进程发送一个信号 功能 向一个或一组进程发送一个信号 语法 include include include include int kill pid sig int kill pid sig pid t pid pid t pid int sig int sig 说明 本系统调用向一个或一组进程发送一个信号 该信号由参数 sig 指 定 为系统给出的信号表中的一个 若为 0 空信号 则检查错误但 实际上并没有发送信号 用于检查 pid 的有效性 pid 指定将要被发送信号的进程或进程组 pid 若大于 0 则信号将 被发送到进程号等于 pid 的进程 若 pid 等于 0 则信号将被发送到所 有的与发送信号进程同在一个进程组的进程 系统的特殊进程除 外 若 pid 小于 1 则信号将被发送到所有进程组号与 pid 绝对值 相同的进程 若 pid 等于 1 则信号将被发送到所有的进程 特殊系 统进程除外 信号要发送到指定的进程 首先调用进程必须有对该进程发送信 号的权限 若调用进程有合适的优先级则具备有权限 若调用进程 的实际或有效的 UID 等于接收信号的进程的实际 UID 或用 setuid 系统调用设置的 UID 或 sig 等于 SIGCONT 同时收发双方进程的会话 号相同 则调用进程也有发送信号的权限 若进程有发送信号到 pid 指定的任何一个进程的权限则调用成功 否则调用失败 没有信号发出 返回值 调用成功则返回 0 否则返回 1 例子 假设前一个例子进程号为 324 现向它发一个 SIGINT 信号 让它做 信号处理 kill pid t 324 SIGINT 2 12 alarm 设置一个进程的超时时钟设置一个进程的超时时钟 功能 设置一个进程的超时时钟 语法 include unistd h include unistd h unsigned int alarm sec unsigned int alarm sec unsigned int sec unsigned int sec 说明 指示调用进程的超时时钟在指定的时间后向调用进程发送一个 SIGALRM 信号 设置超时时钟时时间值不会被放入堆栈中 后一次 设置会把前一次 还未到超时时间 冲掉 若 sec 为 0 则取消任何以前设置的超时时钟 fork 会将新进程的超时时钟初始化为 0 而当一个进程用 exec 族系统调用新的执行文件时 调用前设置的超时时钟在调用后仍 有效 返回值 返回上次设置超时时钟后到调用时还剩余的时间秒数 例子 int flag 0 void myself flag 1 printf get signal SIGALRM n 若要重新设置 SIGALRM 信号中断处理函数为本函数则执行 以下步骤 void a a myself signal SIGALRM a flag 2 main alarm 100 100 秒后发超时中断信号 while 1 sleep 2000 等待中断信号 if flag 1 printf skip system call sleep n exit 0 if flag 2 printf skip system call sleep n printf waiting for next signal n 2 13 msgsnd 发送消息到指定的消息队列中发送消息到指定的消息队列中 功能 发送消息到指定的消息队列中 语法 include include include include include include int msgsnd msqid msgp msgsz msgflg int msgsnd msqid msgp msgsz msgflg int msqid int msqid void msgp void msgp size t msgsz size t msgsz int msgflg int msgflg 说明 发送一个消息到由 msqid 指定消息队列标识号的消息队列 参数 msgp 指向一个用户定义的缓冲区 并且缓冲区的第一个域应 为长整型 指定消息类型 其他数据放在缓冲区的消息中其他正文 区内 下面是消息元素定义 long mtype char mtext mtype 是一个整数 用于接收进程选择消息类型 mtext 是一个长度为 msgsz 字节的任何正文 参数 msgsz 可从 0 到系 统允许的最大值间变化 msgflg 指定操作行为 若 msgflg int msqid void msgp void msgp int msgsz int msgsz long msgtyp long msgtyp int msgflg int msgflg 说明 本系统调用从由 msqid 指定的消息队列中读取一个由 msgtyp 指定 类型的消息到由 msgp 指向的缓冲区中 同样的 该缓冲区的结构如 前所述 包括消息类型和消息正文 msgsz 为可接收的消息正文的 字节数 若接收到的消息正文的长度大于 msgsz 则会被截短到 msgsz 字节为止 当消息标志 msgflg int msqid cmd struct msqid ds buf struct msqid ds buf 说明 本系统调用提供一系列消息控制操作 操作动作由 cmd 定义 以下 cmd 定义值表明了各操作动作的定义 IPC STAT 将 msqid 相关的数据结构中各个元素的当前值放入由 buf 指向的结构中 IPC SET 将 msqid 相关的数据结构中的下列元素设置为由 buf 指 向的结构中的对应值 msg perm uid msg perm gid msg perm mode msg qbytes 本命令只能由有效 UID 等于 msg perm cuid 或 msg perm uid 的 进程或有效 UID 有合适权限的进程操作 只有具有合适权限的 用户才能增加 msg qbytes 的值 IPC RMID 删除由 msqid 指示的消息队列 将它从系统中删除并 破坏相关的数据结构 本命令只能由有效 UID 等于 msg perm cuid 或 msg perm uid 的 进程或有效 UID 有合适权限的进程操作 返回值 调用成功则返回值为 0 否则为 1 2 16 msgget 取得一个消息队列取得一个消息队列 功能 取得一个消息队列 语法 include include include include include include int msgget key msgflg int msgget key msgflg key t key key t key int msgflg int msgflg 说明 本系统调用返回与参数 key 相关的消息队列的标识符 若以下事实成立 则与消息队列相关的标识符和数据结构将被创 建出来 若参数 key 等于 IPC PRIVATE 若参数 key 没有一个已存在的消息队列标识符与之相关 同时值 msgflg否则返回值为 1 例子 本例将包括上述所有消息队列操作的系统调用 define RKEY 0 x9001L 读消息队列的 KEY 值 define WKEY 0 x9002L 写消息队列的 KEY 值 define MSGFLG 0666 消息队列访问权限 define IPC WAIT 0 等待方式在 include 文件中未定义 int rmsqid 读消息队列标识符 int wmsqid 写消息队列标识符 struct msgbuf long mtype char mtext 200 buf 若读消息队列已存在就取得标识符 否则则创建并取得标识符 if rmsqid msgget RKEY MSGFLG IPC CREAT 0 printf get read message queue failed n exit 1 若写消息队列已存在则失败 若不存在则创建并取得标识符 if wmsqid msgget WKEY MSGFLG IPC CREAT IPC TRUNC 0 printf get ld type message from queue s n buf mtype buf mtext else printf get message failed n exit 3 buf mtype 3L if msgsnd wmsqid else printf send message failed n exit 4 msgctl wmsqid IPC RMID struct msqid NULL 2 17 shmat 联接共享内存的操作联接共享内存的操作 功能 联接共享内存的操作 语法 include include include include include include void shmat shmid shmaddr shmflg void shmat shmid shmaddr shmflg int shmid int shmid void shmaddr void shmaddr int shmid int shmid 说明 将由 shmid 指示的共享内存联接到调用进程的数据段中 被联接的 段放在地址 该地址由以下准则指定 若 shmaddr 等于 void 0 则段联接到由系统选择的第一个可 用的地址上 若 shmaddr 不等于 void 0 同时 shmflg否则 若值不为真且调用进程有读写权限 则被联接 的段为可读写的 返回值 若调用成功则返回被联接的共享内存段在数据段上的启始地址 否则返回值为 1 2 18 shmdt 断开共享内存联接的操作断开共享内存联接的操作 功能 断开共享内存联接的操作 语法 include include include include include include void shmdt shmaddr void shmdt shmaddr void shmaddr void shmaddr 说明 本系统调用将由 shmaddr 指定的共享内存段从调用进程的数据段 脱离出去 返回值 若调用成功则返回值为 0 否则返回值为 1 2 19 shmget 取得共享内存段取得共享内存段 功能 取得共享内存段 语法 include include include include include include int shmget key size shmflg int shmget key size shmflg key t key key t key int size shmflg int size shmflg 说明 本系统调用返回 key 相关的共享内存标识符 共享内存标识符和相关数据结构及至少 size 字节的共享内存段能 正常创建 要求以下事实成立 参数 key 等于 IPC PRIVATE 参数 key 没有相关的共享内存标识符 同时 shmflg d cmd struct shmid ds buf struct shmid ds buf 说明 本系统调用提供一系列共享内存控制操作 操作行为由 cmd 指定 以下为 cmd 的有效值 IPC STAT 将 shmid 相关的数据结构中各个元素的当前值放入由 buf 指向的结构中 IPC SET 将 shmid 相关的数据结构中的下列元素设置为由 buf 指 向的结构中的对应值 shm perm uid shm perm gid shm perm mode 本命令只能由有效 UID 等于 shm perm cuid 或 shm perm uid 的 进程或有效 UID 有合适权限的进程操作 IPC RMID 删除由 shmid 指示的共享内存 将它从系统中删除并 破坏相关的数据结构 本命令只能由有效 UID 等于 shm perm cuid 或 shm perm uid 的 进程或有效 UID 有合适权限的进程操作 返回值 若调用成功则返回 0 否则返回 1 例子 本例包括上述所有共享内存操作系统调用 include include include define SHMKEY 74 define K 1024 int shmid cleanup shmctl shmid IPC RMID 0 exit 0 main int pint char addr1 addr2 extern char shmat extern cleanup for i 0 i 20 i signal i cleanup shmid shmget SHMKEY 128 K 0777 IPC CREAT addr1 shmat shmid 0 0 addr2 shmat shmid 0 0 printf addr1 0 x x addr2 0 x x n addr1 addr2 pint int addr1 for i 0 i 256 i pint i pint int addr1 pint 256 pint int addr2 for i 0 i 256 i printf index d tvalue d n i pint shmdt addr1 shmdt addr2 pause 2 21 semctl 信号量控制操作信号量控制操作 功能 信号量控制操作 语法 include include include include include include int semctl semid memnum cmd arg int semctl semid memnum cmd arg int semid semnum cmd int semid semnum cmd union semun union semun int val int val struct semid ds buf struct semid ds buf ushort array ushort array arg arg 说明 本系统调用提供了一个信号量控制操作 操作行为由 cmd 定义 这 些命令是对由 semid 和 semnum指定的信号量做操作的 每个命令都 要求有相应的权限级别 GETVAL 返回 semval 的值 要求有读权限 SETVAL 设置 semval 的值到 arg val 上 此命令成功执行后 semadj 的值对应的所有进程的信号量全部被清除 要求有修 改权限 GETPID 返回 sempid 的值 要求有读权限 GETNCNT 返回 semncnt 的值 要求有读权限 GETZCNT 返回 semzcnt 的值 要求有读权限 以下命令在一组信号量中的各个 semval 上操作 GETALL 返回每个 semval 的值 同时将各个值放入由 arg array 指向的数组中 当此命令成功执行后 semadj 的值对应的所有 进程的信号量全部被清除 要求有修改权限 SETALL 根据由 arg array 指向的数组设置各个 semval 值 当此 命令成功执行后 semadj 的值对应的所有进程的信号量全部 被清除 要求有修改权限 以下命令在任何情况下都是有效的 IPC STAT 将与 semid 相关的数据结构的各个成员的值放入由 arg buf 指向的结构中 要求有读权限 IPC SET 设置 semid 相关数据结构的如下成员 设置数据从 arg buf 指向的结构中读取 sem perm uid sem perm gid sem perm mode 本命令只能由有效 UID 等于 sem perm cuid 或 sem perm uid 的 进程或有效 UID 有合适权限的进程操作 IPC RMID 删除由 semid 指定的信号量标识符和相关的一组信号 量及数据结构 本命令只能由有效 UID 等于 sem perm cuid 或 sem perm uid 的进程或有效 UID 有合适权限的进程操作 返回值 若调用成功 则根据 cmd 返回以下值 GETVAL semval 的值 GETPID sempid 的值 GETNCNT semncnt 的值 GETZCNT semzcnt 的值 其他 0 若调用失败则返回 1 2 22 semget 取得一组信号取得一组信号量量 功能 取得一组信号量 语法 include include include include include include int semget key nsems semflg int semget key nsems semflg key t key key t key int nsems semflg int nsems semflg 说明 返回和 key 相关的信号量标识符 若以下事实成立 则与信号量标识符 与之相关的 semid ds 数据结 构及一组 nsems 信号量将被创建 key 等于 IPC PRIVATE 系统内还没有与 key 相关的信号量 同时 semflg否则返回 1 2 23 semop 信号量操作信号量操作 功能 信号量操作 语法 include include include include include include int semop semid sops nsops int semop semid sops nsops int semid int semid struct sembuf sops struct sembuf sops unsigned nsops unsigned nsops 说明 本系统调用用于执行用户定义的在一组信号量上操作的行为集合 该组信号量与 semid 相关 参数 sops 为一个用户定义的信号量操作结构数组指针 参数 nsops 为该数组的元素个数 数组的每个元素结构包括如下成员 sem num 信号量数 sem op 信号量操作 sem flg 操作标志 由本系统调用定义的每个信号量操作是针对由 semid 和 sem num指 定的信号量的 变量 sem op 指定三种信号量操作的一种 若 sem op 为一负数并且调用进程具有修改权限 则下列情况之 一将会发生 若 semval 不小于 sem op 的绝对值 则 sem op 的绝对值被减去 semval 的值 若 semflg unsigned int count 在文件 sys sem h 中定义的 sembuf 结构 struct sembuf unsigned short sem num short sem op short sem flg struct sembuf psembuf vsembuf P 和 V 操作 cleanup semctl semid 2 IPC RMID 0 exit 0 main argc argv int argc char argv int i first second short initarray 2 outarray 2 extern cleanup if argc 1 for i 0 i 20 i signal i clearup semid semget SEMKEY 2 0777 IPC CREAT initarray 0 initarray 1 1 semctl semid 2 SETALL initarray semctl semid 2 GETALL outarray printf sem init vals d d n outarray 0 outarray 1 pause 睡眠到被一软件中断信号唤醒 else if argv 1 0 a first 0 second 1 else first 1 second 0 semid semget SEMKEY 2 0777 psembuf sem op 1 psembuf sem flg SEM UNDO vsembuf sem op 1 vsembuf sem flg SEM UNDO for count 0 xcount psembuf sem num first semop semid psembuf sem num second semop semid printf proc d count d n getpid count vsembuf sem num second semop semid vsembuf sem num first semop semid 2 24 sdenter 共享数据段同步访问共享数据段同步访问 加锁加锁 功能 共享数据段同步访问 加锁 语法 include sys sd h include sys sd h int sdenter addr flags int sdenter addr flags char addr char addr int flags int flags 说明 用于指示调用进程即将可以访问共享数据段中的内容 参数 addr 为将一个 sdget 调用的有效返回码 所执行的动作取决于 flags 的值 SD NOWAIT 若另一个进程已对指定的段调用本系统调用且还没 有调用 sdleave 并且该段并非用 SD UNLOCK 标志创建 则调 用进程不是等待该段空闲而是立即返回错误码 SD WRITE 指示调用进程希望向共享数据段写数据 此时 另一 个进程用 SD RDONLY 标志联接该共享数据段则不被允许 返回值 调用成功则返回 0 否则返回 1 2 25 sdleave 共享数据段同步访问共享数据段同步访问 解锁解锁 功能 共享数据段同步访问 解锁 语法 include sys sd h include sys sd h int sdleave addr flags int sdleave addr flags char addr char addr 说明 用于指示调用进程已完成修改共享数据段中的内容 返回值 调用成功则返回 0 否则返回 1 2 26 sdget 联接共享数据段到调用进程的数据空间中联接共享数据段到调用进程的数据空间中 功能 联接共享数据段到调用进程的数据空间中 语法 include include char sdget path flags size mode char sdget path flags size mode char path char path int flags int flags long size long size int mode int mode 说明 本系统调用将共享数据段联接到调用进程的数据段中 具体动作 由 flags 的值定义 SD RDONLY 联接的段为只读的 SD WRITE 联接的段为可读写的 SD CREAT 若由 path 命名的段存在且不在使用中 本标志的作用 同早先创建一个段相同 否则 该段根据 size 和 mode 的值进程 创建 对段的读写访问权限的授予基于 mode 给的权限 功能与 一般文件的相同 段被初始化为全 0 SD UNLOCK 若用此标志创建该段 则允许有多个进程同时访问 在读写中 该段 返回值 若调用成功则返回联接的段地址 否则返回 1 2 27 sdfree 将共享数据段从调用进程的数据空间中断将共享数据段从调用进程的数据空间中断 开联开联接接 功能 将共享数据段从调用进程的数据空间中断开联接 语法 include include int sdfree addr int sdfree addr char addr char addr 说明 本系统调用将共享数据段从调用进程的数据段的指定地址中分离 若调用进程已完成 sdenter 的调用 还未调用 sdleave 就调用 本系统调用 则 sdleave 被自动调用 然后才做本调用的工作 返回值 若调用成功则返回联接的段地址 否则返回 1 2 28 sdgetv 同步共享数据访问同步共享数据访问 功能 同步共享数据访问 语法 include include int sdgetv addr int sdgetv addr char addr char addr

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论