第15章 进程间通信(IPC)
许多程序都包含一个或多个进程.进程间通过共享数据或传递数据进行通信.举例来说, 两个人通过使用Unix的talk命令进行对话,他们就运行了两个进程,将数据从键盘和socket 传输到屏幕和socket
某些进程需要从多个源端接受数据,并将数据送到多个目的地.select和poll调用允许进程 等待多个文件描述符的输入
Unix提供了许多方法来进行数据在进程间传输,命名管道和共享内存是同一机器上的进程间 通信使用的两种技术.通信方法的区别在于他们的速度,所传输的消息类型,需要的范围, 限制访问权限的能力以及防止数据冲突的能力
文件锁是进程间使用的避免对文件访问冲突的技术
信号量是进程合作时所使用的系统级的变量.进程挂起等待另一进程改变信号量的值
纵观IPC: fork-execv-argv, exit-wait 用于使用一组参数来调用某个程序,被调用函数将一个整形值返回给其调用者 面向消息,只能用在相关的进程中,且只能单机上使用
environ 系统调用exec通过environ这个全局变量自动将一组字符串复制给新程序,子进程无法改变 父进程的运行环境 面向对象,单向,只能用在相关进程,且只能在单机上使用
pipe 管道是由进程创建的单向数据流 面向流,单向,相关进程,单机
kill-signal 信号是一条从一个进程发往另一个进程的整形消息 面向消息,单向,进程必须有相同的用户ID,单机
Internet sockets 字节流通过socket进行传输,从一个进程到另一个进程 面向消息,面向流,双向传输,可以在无关进程中使用,可通过网络传输
Named Sockets 命名socket,使用文件名作为地址而不是主机名-端口号对 面向消息,面向流,双向传输,可以在无关进程中使用,单机
Named Pipes(FIFOs) 命令管道工作方式类似于常规管道,但是可以连接两个无关进程 单向,面向流,可以连接无关进程,单机
File Locks 文件锁 面向消息,多个无关进程可同时交互,单机
Shared Memory 每个进程有自己的数据空间,进程可以通过shmget shmat调用来创建可以被多个进程共享的内存段 面向随即访问,多个无关进程同时交互,单机
Semaphores 信号量是系统级的变量,程序之间可以通过信号量进行通信 面向消息,多个无关进程同时交互,单机
Message Queues 消息队列工作原理类似FIFO 面向消息,单向传输,单机
Files 文件可以被多个进程在同一时刻打开 面向随即访问,多个无关进程同时交互,网络文件系统(NFS)可以支持跨机器的多进程通信
code
代码语言:javascript复制/*
* shm_ts.c
*
* the time server using shared memory, a bizarre application
*/
#include <stdio.h>
#include <sys/shm.h>
#include <time.h>
#define TIME_MEM_KEY 99
#define SEG_SIZE ((size_t)100)
main()
{
int seg_id;
char * mem_ptr, *ctime();
long now;
int n;
// create a shared memory segment
seg_id = shmget(TIME_MEM_KEY, SEG_SIZE, IPC_CREAT|0777);
if (seg_id == -1)
printf("error");
// attach to it and get a pointer to where it attaches
mem_ptr = shmat(seg_id, NULL, 0);
if (mem_ptr == (void *)-1)
printf("error");
// run for a minute
for (n = 0; n < 60; n )
{
time(&now);
strcpy(mem_ptr, ctime(&now));
sleep(1);
}
// remove it
shmctl(seg_id, IPC_RMID, NULL);
}
代码语言:javascript复制/*
* shm_tc.c
*/
#include <stdio.h>
#include <sys/shm.h>
#include <time.h>
#define TIME_MEM_KEY 99
#define SEG_SIZE ((size_t)100)
main()
{
int seg_id;
char * mem_ptr, *ctime();
long now;
// create a shared memory segment
seg_id = shmget(TIME_MEM_KEY, SEG_SIZE, 0777);
if (seg_id == -1)
printf("error");
// attach to it and get a pointer to where it attaches
mem_ptr = shmat(seg_id, NULL, 0);
if (mem_ptr == (void *)-1)
printf("error");
printf("Time is %s", mem_ptr);
shmdt(mem_ptr);
}