亚博yaboapp Linux下C语言应用编程之进程间通信_计算机软件及应用_IT/计算机_专业资料

2021-01-24 13:07:57 浏览: 187次 来源:【jake推荐】 作者:-=Jake=-

进程间通信进程间通信概述? 进程间通信有如下一些目的:?数据传输:一个进程需要将它的数据发送给另一个进 程。?共享数据:多个进程想要操作共享数据,一个进程对 共享数据的修改,别的进程应该立刻看到。?通知事件:一个进程需要向另一个或一组进程发送消 息凤凰体育 ,通知它(它们)发生了某种事件(如进程终止时 要通知父进程)。?资源共享的同步:多个进程之间共享同样的资源。为 了作到这一点,需要内核提供锁和同步机制。?进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。Linux下C语言应用编程进程间通信概述? linux进程间通信(IPC)由以下几部分发展而来: ? 早期UNIX进程间通信、基于System V进程间通信、 基于Socket进程间通信和POSIX进程间通信。 ? UNIX进程间通信方式包括:管道、FIFO、信号。 ? System V进程间通信方式包括:System V消息队 列、System V信号灯、System V共享内存。 ? POSIX进程间通信包括:posix消息队列、posix信 号灯、posix共享内存。

Linux下C语言应用编程进程间通信概述? 现在linux使用的进程间通信方式: ? (1)无名管道(pipe)和有名管道(FIFO) ? (2)消息队列 ? (3)共享内存 ? (4)信号量 ? (5)信号(signal) ? (6)套接字(socket)Linux下C语言应用编程信号概述? 信号是软件中断。信号(signal)机制是Unix系统中最 为古老的进程之间的通信机制。它用于在一个或多 个进程之间传递异步信号。? 产生信号:? 当用户按某些终端键时,可以产生信号。例如: 在终端上按Ctrl-C键通常产生中断信号 (SIGINT)。这是停止一个已失去控制程序的方 法。? 硬件异常产生信号:除数为0、无效的存储访问 等等。这些条件通常由硬件检测到,并将其通知 内核。然后内核为该条件发生时正在运行的进程 产生适当的信号。例如,对执行一个无效存储访 问的进程产生一个SIGSEGV。Linux下C语言应用编程Linux 中的信号Linux下C语言应用编程信号? 下面是几个常见的信号。? SIGHUP: 从终端上发出的结束信号; ? SIGINT: 来自键盘的中断信号(Ctrl-C); ? SIGQUIT:来自键盘的退出信号(Ctrl-\); ? SIGFPE: 浮点异常信号(例如浮点运算溢出); ? SIGKILL:该信号结束接收信号的进程; ? SIGALRM:进程的定时器到期时,发送该信号; ? SIGTERM:kill 命令发出的信号; ? SIGCHLD:标识子进程停止或结束的信号; ? SIGSTOP:来自键盘(Ctrl-Z)或调试程序的停止执行信号? ………… Linux下C语言应用编程信号? 可以要求系统在某个信号出现时按照下列三种方式中的一种 进行操作。

? (1) 忽略此信号。大多数信号都可使用这种方式进行处理,但有两种 信号却决不能被忽略。它们是:SIGKILL和SIGSTOP。这两种信号 不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止 的可靠方法。另外,如果忽略某些由硬件异常产生的信号(例如非 法存储访问),则进程的行为是未定义的。? (2) 捕捉信号。为了做到这一点要通知内核在某种信号发生时,调用 一个用户函数。在用户函数中c语言进程间通信,可执行用户希望对这种事件进行的 处理。如果捕捉到SIGCHLD信号,则表示子进程已经终止,所以此 信号的捕捉函数可以调用waitpid以取得该子进程的进程ID以及它的 终止状态。? (3) 执行系统默认动作。对大多数信号的系统默认动作是终止该进程。Linux下C语言应用编程信号处理函数? #include ? __sighandler_t signal(int __sig, __sighandler_t _handler); ? 功能:信号处理函数。 ? 返回值:成功返回可用信号处理函数,失败返回SIG_ERR。 ? 参数:? __sig,要捕获的信号。 ? __handler,信号处理函数。

还可以是以下取值: ? SIG_IGN 屏蔽该信号 ? SIG_DFL 恢复默认行为? 注:该函数简单但可靠性低,可由sigaction()代替。Linux下C语言应用编程信号处理函数? #include? int kill(__pid_t __pid, int __sig); ? 功能:发送信号到进程。 ? 返回值:成功返回0,否则返回-1。? #include? int alarm(unsigned int __seconds);? 功能: 在__secends秒后发送SIGALARM信号。若 __secends为0,则取消已设置闹铃。? 返回值:成功返回上一个闹铃还剩余多长时间,失败返回-1。Linux下C语言应用编程管道通信? 管道通信例如:? ps | grep vsftpd ? 管道是单向的、先进先出的、无结构的字节流,它把一个 进程的输出和另一个进程的输入连接在一起。写进程在管道的 尾端写入数据,读进程在管道的首端读出数据。数据读出后将 从管道中移走,其它读进程都不能再读到这些数据。管道提供 了简单的流控制机制。进程试图读空管道时澳洲幸运5官网 ,在有数据写入管 道前,进程将一直阻塞。

同样鸭脖娱乐 ,管道已经满时,进程再试图写 管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。 ? 管道主要用于不同进程间通信。Linux下C语言应用编程管道通信? 管道有一些固有的局限性:? 因为读数据的同时也将数据从管道移去,因此, 管道不能用来对多个接收者广播数据。? 管道中的数据被当作字节流,因此无法识别信息 的边界。? 如果一个管道有多个读进程c语言进程间通信,那么写进程不能发 送数据到指定的读进程。同样,如果有多个写进 程,那么没有办法判断是它们中那一个发送的数 据。Linux下C语言应用编程管道函数? #include ? int pipe(int fd[2]); ? 功能:创建一个简单的管道,若成功则为数组fd分配两个文件描述符,其中fd[0] 用于读取管道,fd[1] 用于写入管道。 ? 返回值:成功返回0,失败返回- 1。pipe 调用成 功后的 状况Linux下C语言应用编程fd[0] fd[1]管道(续)父进程 fd[0]fd[1]子进程 fd[0]fd[1]管道 内核单个进程中的管道父进程fd[1]管道内核父子进程共享的管道子进程 fd[0]管道父子进程共享的管道内核Linux下C语言应用编程? 管道写端关闭,读端再读取管道时将返回0 ? 管道读端关闭,写端再写管道时将产生sigpipe信号,该信号的默认行为是结束进程Linux下C语言应用编程有名管道(FIFO)? 有名管道和一般的无名管道基本相同,但也 有一些显著的不同:? 有名管道是在文件系统中作为一个特殊的文件而 存在的。

? 不同祖先的进程之间可以通过有名管道共享数据。 ? 当共享管道的进程执行完所有的I / O操作以后,有名管道将继续保存在文件系统中以便以后使用。 ? 无名管道只能由相关进程使用,它们共同的祖先进程创建了管道。但是,通过FIFO,不相关的进 程也能交换数据。Linux下C语言应用编程创建命名管道? #include ? #include ? int mkfifo(const char * pathname, mode_tmode) ; ? 功能:创建命名管道 ? 返回:若成功则为0,若出错则为- 1Linux下C语言应用编程共享内存? 共享内存区域是被多个进程共享的一部分物 理内存。如果多个进程都把该内存区域映射 到自己的虚拟地址空间,则这些进程就都可 以直接访问该共享内存区域,从而可以通过 该区域进行通信。? 共享内存是进程间共享数据的一种最快的方 法,一个进程向共享内存区域写入了数据, 共享这个内存区域的所有进程就可以立刻看 到其中的内容。Linux下C语言应用编程共享内存进程一共享内存进程二共享内存原理示意图Linux下C语言应用编程共享内存? #include? int shmget(key_t __key, size_t __size, int __shmflg); ? 功能:创建共享内存。

? 返回值:成功返回共享内存标识码,失败返回-1。 ? 参数:? __key,标识共享内存的键值 。 ? __size,要建立共享内存的长度。 ? __shmflg,标志。其中有效的包括: ? IPC_CREAT 如果共享内存不存在,则创建一个共享内存,否则获得该共享内存。? IPC_EXCL 只有在共享内存不存在的时候,新 的共享内存才建立,否则就产生错误。Linux下C语言应用编程共享内存? #include ? void *shmat(int shmid, const void *shmaddr, int shmflg); ? 功能:允许进程访问一块共享内存(共享内存刚创建时不能使用),即:映射一块共享内存。 ? 返回值:成功返回共享内存的虚拟地址起始地址,失败返回-1。 ? 参数:? shmid是共享内存的ID。 ? *shmaddr是共享内存在本进程内的起始地址 ? shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。Linux下C语言应用编程共享内存? #include ? int shmdt(const void *shmaddr); ? 功能:断连共享内存区的映射。

? 返回值:成功时返回0。失败时返回-1。 ? 参数:? shmaddr是共享内存的虚拟地址起始地址。Linux下C语言应用编程共享内存? 利用共享内存进行进程间通信的实例 ? 利用共享内存进行进程间通信时存在的同步问题 ? 如何解决? —— 信号量Linux下C语言应用编程信号量(semaphore)? #include ? int semget(key_t __key, int __nsems, int__semflg); ? 功能:创建一个新的信号量或取得一个新的信号量。 ? 返回值:成功返回信号量标志码,失败返回-1。 ? 参数:? __key,整型值,其它进程访问信号量的依据。 ? __nsems,信号量个数,一般为1。 ? __semflg,标志,类似open()的标志,相当于文件的访问权限。Linux下C语言应用编程信号量? #include? int semctl(int __semid, int __semnum, int __cmd, …);? 功能:控制信号量信息。? 返回值:成功返回0,否则-1。? 参数:? __semid,信号量标志码。? __semnum,信号量编号。

? __cmd,要进行的操作。? 第四个参数,是union semun的实例华体会体育 ,具体值依赖__cmd。Linux下C语言应用编程信号量__cmd允许的命令: ? IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。 ? IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。 ? IPC_RMID将信号量集从内存中删除。 ? GETALL用于读取信号量集中的所有信号量的值。 ? GETNCNT返回正在等待资源的进程数目。 ? GETPID返回最后一个执行semop操作的进程的PID。 ? GETVAL返回信号量集中的一个单个的信号量的值。 ? GETZCNT返回这在等待完全空闲的资源的进程数目。 ? SETALL设置信号量集中的所有的信号量的值。 ? SETVAL设置信号量集中的一个单独的信号量的值。Linux下C语言应用编程信号量? #include ? int semop(int __semid, struct sembuf*__sops, size_t __nsops); ? 功能:用户改变信号量的值。

? 返回值:成功返回0,否则-1。 ? 参数:? __semid,信号量标志码。 ? __sops,结构体指针凤凰彩票代理 ,包含了具体操作。 ? __nsops,结构体数量,等于1。Linux下C语言应用编程信号量? struct sembuf?{? unsigned short sem_num;? shortsem_op;? shortsem_flg;? };? 这三个字段的意义分别为:? sem_num:操作信号在信号集中的编号,第一个信号的编号是0。? sem_op:如果其值为正数,该值会加到现有的信号内含值中。通常用 于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大 于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对 值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时 阻塞,直到信号的值变为0。? sem_flg:信号操作标志,可能的选择有两种? IPC_NOWAIT //对信号的操作不能满足时,semop()不会阻塞,并立即 返回,同时设定错误信息。? IPC_UNDO //程序结束时(不论正常或不正常),保证信号值会被重设为 semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时 未将锁定的资源解锁,造成该资源永远锁定。Linux下C语言应用编程

老王