进程是一个独立的资源分配单元,不同进程之间进程是独立的。
Linux操作系统支持的进程间通信机制:
(1)、同主机进程间数据交互机制:无名管着(PIPE)、有名管道(FIFO)、消息队列(Message Queue)和共享内存(Share Memory)。
(2)、同主机进程间同步机制:信号量(semaphore)
(3)、同主机进程间异步机制:信号(Signal)
(4)、网络主机间数据交互机制:套接口(Socket)。
一、无名管道(PIPE):
普通的Linux shell都允许重定向,而重定向使用的就是管道。
int pipe(int fd[2]); 管道创建
注意:fd[0]用于读取管道,fd[1]用于写入管道。管道主要用于不同进程间通信。实际上,通常先创建一个管道,再通过fork函数创建一个子进程。
二、有名管道(FIFO)
无名管道是临时的,在完成通信后将自动消失,且只能在具有亲缘关系的进程间实现通信。有名管道可以在不同进程间通信。
int mkfifo(const char *pathname,mode_t mode);
注:在使用有名管道时,一定要使用两个进程分别打开其读端与写端
三、信号(signal):
信号是软件中断。信号(signal)机制是Unix系统中最为古老的进程之间的能信机制。它用于在一个或多个进程之间传递异步信号。
1、 信号的发送与捕捉
kill()和raise()
kill()不仅可以中止进程,也可以向进程发送其他信号。
与kill函数不同的是,raise()函数运行向进程自身发送信号
#include<sys/types.h>
#include<signal.h>
int kill(pid_t pid,int signo);
int raise(int signo);
2、 信号的处理
void (*signal (int signo,void (*func)(int)))(int)
第一个参数signo为接收的信号,第二个参数为接收到此信号后的处理代码入口(即处理子程序)
四、System V 进程间通信
System V提供的IPC机制主要有消息队列、信号量和共享内存3种机制,和linux系统中文件一样,都有自己的读写属性,但其读写操作不能使用普通文件的read/write方式。任何一个IPC通信对象都用唯一的ID来标识自己,以使其他进程能够通过此ID值访问它,从而实现信息的交互。
1、 消息队列
主要用来实现两个进程间少量的数据传输,并且接收方可以根据消息队列中消息的类型选择性地接收消息。
key_t ftok (char*pathname, char proj); 它返回与路径pathname相对应的一个键值
int msgget(key_t key, int msgflg) 将创建一个新的消息队列
int msgrcv(int msqid, struct msgbuf *msgp, int msgsz, long msgtyp, int msgflg);
该系统调用从msgid代表的消息队列中读取一个消息,并把消息存储在msgp指向的msgbuf结构中。
int msgsnd(int msqid, struct msgbuf *msgp, int msgsz, int msgflg);
向msgid代表的消息队列发送一个消息,即将发送的消息存储在msgp指向的msgbuf结构中,消息的大小由msgze指定。
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
该系统调用对由msqid标识的消息队列执行cmd操作,共有三种cmd操作:IPC_STAT、IPC_SET 、IPC_RMID。
2、 信号量通信机制
信号量通信机制主要用来实现进程间同步,信号量值用来标识系统可用资源的个数。
int semget(key_t key, int num_sems, int sem_flags);
创建一个新的信号量或是获得一个已存在的信号量键值。
int semctl(int sem_id, int sem_num, int command, ...);
允许信号量信息的直接控制:
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);
改变信号量的值
第一个参数,sem_id,是由semget函数所返回的信号量标识符。第二个参数,sem_ops,是一个指向结构数组的指针,其中的每一个结构至少包含下列成员:
struct sembuf {
short sem_num;
short sem_op;
short sem_flg;
}
3、 共享内存
主要用于实现进程间大量的数据传输。在使用共享内存进行数据存取时,一般配合二元信号量使用。
int shmget(key_t key, size_t size, int oflag ); 共享内存区的创建和操作:
int shmctl( int shmid , int cmd , struct shmid_ds *buf ); 共享内存控制函数
char *shmat( int shmid , void *shmaddr , int shmflag ); 共享内存区对象映射到调用进程的地址空间
int shmdt( char *shmaddr ); 脱离共享内存块