在实际进程运行中,用户经常要同时创建多个进程,用以分别处理不同的功能,而不同进程间为了完成协同合作,需要进行进程间通信。常见的进程间通信方法有管道、FIFO、消息队列、信号量、共享内存、以及socket等。
管道
用管道实现进程间通信的特点:(一)、管道是半双工的,管道在同一时刻只能单方向的收/发信息,不能收发同时进行;(二)、管道只能在有共同父进程的进程间使用,
管道使用到的pipe()函数定义:
#include<unistd.h>
int pipe(int filedes[2]);
参数filedes返回两个文件描述符,一个filedes[0]是读端,filedes[1]是写段。函数成功运行则返回0,运行失败则返回-1.
函数运行实例:
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int fd[2];
pid_t pid;
char buf[64]="I'm parent process.\n";
char line[64];
if(0 != pipe(fd)) //检验pipe是否运行成功
{
fprintf(stderr,"fail to creat pipe!\n");
trturn 0;
}
pid = fork(); //使用fork函数创建进程
if( pid < 0) //fork函数运行出错
{
fprintf(stderr,"fail to creat process!");
return 0;
}
else if( pid > 0) //父进程,pid返回子进程的进程ID
{
close(fd[0]); //关闭读管道,父进程只能向管道内写入数据。
write(fd[1],buf,strlen(buf)); //把字符串buf写入通道缓存中
close(fd[1]); //关闭写管道
}
else //pid == 0;父进程
{
close(fd[1]); //关闭写通道,只能读
read(fd[0],line,64); //通过字符串line将通道缓存中的数据读出
printf("DATA from parent;%s\n",line);
close(fd[0]); //关闭读通道
}
return 0;
}
以上函数通过pipe()函数实现进程间通信,在父进程将字符串“I’m parent process."写入管道中,在子进程中读出管道中的字符串,并打印于屏幕中。
共享内存
我们可以在内存中开辟一段内存空间,以供不同进程间共享数据,显然共享内存可以实现比管道更大的数据传输量。
共享内存用到的函数定义:
#include<sys/ipc.h>
#include<sys/shm.h>
int shmget(key_t key,size_t size,int shmflg);
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
shmget()函数用来创建共享内存,size参数用来制定需要的共享内存字节数,shmflg标识内存的操作方式,有读或者写两种。共享内存开辟成功,函数返回一个共享内存的ID。
shmat()函数用于获取一个共享内存ID对应的内存起始地址;参数shmid是共享内存ID,shmaddr参数指定了共享内存的地址,若参数是0,则表示让系统分配共享内存地址,如果获取内存地址成功,函数返回对应的共享内存地址。
写共享内存操作代码:
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
int main(void)
{
int shmid;
char *ptr;
char *shm_str = "string is a share memory."
shmid = shmget(0x90,1024,SHM_W | SHM_R | IPC_EXCL); //创建共享内存
if( -1 == shmid )
{
perror("creat share memory.");
}
ptr = (char *)shmat(shmid , 0 , 0 ); //获得共享内存的地址
if((void *)-1 == ptr)
{
perror("get share memory.");
}
strcpy(ptr, shm_str); //将字符串写入共享内存中。
shmdt(ptr);
return 0;
}
读共享内存操作代码:
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>
int main(void)
{
int shmid;
char *ptr;
shmid = shmget(0x90, 1024, SHM_W | SHM_R | IPC_EXCL);
if( -1 == shmid )
{
perror("creat share memory.");
}
ptr = shmat(shmid, 0, 0);
if((void *) -1 == ptr)
{
perror("get share memory");
}
printf("string in share memory is :%S\n",ptr);
shmdt(ptr);
return 0;
}
以上是进程间通信的两种方式,管道和共享内存,进程间通信的其他方式补充会在后续文章展开。