C语言进程——进程间的通信方式

进程间通信就是在不同进程之间传播或交换信息,进程的用户空间是相互独立的,一般而言是不可以互相访问(除共享内存区外),系统空间却是“公众场所”,通过通信方法:管道(pipe)(有名管道FIFO)、消息队列、信号量(semaphore)、共享内存(shared memory)、套接字(socket)等实现功能。

进程间通信的主要目的在于:数据传输(管道pipe),共享数据,通知事件,资源共享,进程控制

管道通信:管道是单向的,先进先出,尾部写入数据,头部读出数据

无名管道用于父子进程间的通信,有名管道用于同一系统下的兄弟进程间的通信。

无名管道创建API:int pipe(int filedis[2])(当一个管道建立,会产生两个文件描述符,filedis[0]读管道,filedis[1]写管道)

有名管道创建API:int mkfifo(const char *pathname,mode_t mode)(pathname:FIFO文件名  mode:属性)

信号通信:最为古老的进程间通信机制

常见信号:SIGHUP(来自终端的结束信号) 、SIGINT(来自键盘的中断信号) 、SIGKILL(结束接收信号) 、SIGTERM(kill命令发出的信号) 、SIGCHLD(标识子进程停止或结束) 、SIGSTOP(停止执行信号)【SIGKILL、SIGSTOP绝不可以被忽略】

信号发送kill、raise、alarm、pause的API:

int kill(pid_t pid,int signo)
//kill函数既可向自身发送信号,也可向其他进程发送信号
int raise(int signo)
//raise函数是向自身发送信号
unsigned int alarm(unsigned int seconds)
/*alarm函数是设置一个闹钟时间
seconds:经过second秒后会产生信号SIGALRM*/
int pause(void)
//该函数是使调用过程挂起直至捕捉到一个信号

信号的处理:
signal的API:void(*signal(int signum,void(*handler)(int)))(int);
共享内存
被多个进程共享的一部分物理内存,共享进程是进程间共享数据的一种最快的方法


创建API:int shmget(key_t key,int size,int shmflg) 成功返回共享内存标识符,失败返回-1

映射API:char *shmat(int shmid,char *shmaddr,int flag) 成功返回共享内存映射到进程中的地址,失败返回-1

消息:

#include
#include
#include
//消息格式
struct msgbuf
{
    long mtype;//消息类型
    char mtext[1];//消息数据的首地址
};

int msgsnd(int msqid,struct msgbuf *msgp,int msgsz,int msgflg)
//功能:向消息队列中发送一条消息

int msgrcv(int msqid,struct msgbuf *msgp,int msgsz,long msgtyp,int msgflg)
//功能:接收消息,从msqid代表的消息队列中读取一个msgtyp类型的消息;成功则返回读出消息的字节数

int msgget(key_t key,int msgflg)
//key为键值,由ftok获得;msgflg为标志位
//返回值为与键值key相对应的消息队列描述字

key_t ftok(char *pathname,char proj);
//将文件名转化为键值
key: IPC_CREAT、IPC_EXCL、IPC_NOWAIT

总结:

进程间的通信中关于管道通信时,Linux将不保证写入的原子性(即不保证完整的完成一个进程),只要管道缓冲区有空闲区域,写进程就会试图向管道中写入数据,若读进程不读走缓冲区中的数据,写操作将一直被阻塞。创建无名管道时,父子进程fork()的使用必须在pipe()调用之后。注意:alarm函数使用时,每个进程至多有一个闹钟时间,若以前登记过,且未超时,此时登记新的值,值>0则取代之前的值,值=0则为取消以前的闹钟。



你可能感兴趣的:(进程ID)