Linux下C编程:进程间通信(IPC)总结
2014-07-12 23:41
639 查看
(1)Linux信号:
某种信号相当于某种事件,一般用于内核告诉进程某种事件发生了,进程通过signal函数注册信号的处理函数。我个人体会在用户态中两个进程之间用信号进行进程间通信应该不是一个特别好的方法,限制比较多。
(2)匿名管道:
int pipe(int fdes[2]);//创建匿名管道
管道的都写方法和文件文件读写方法相同
匿名管道一般用在父进程和子进程之间的数据通信,而且匿名管道是在内核中临时存储的,程序运行结束后,就不存在了。
(3)命名管道:任何两个进程之间都可以通过命名管道去通信,命名管道是作为特殊设备文件存储在文件系统中的,当程序运行结束后,它继续存在于文件系统中,除非删除该文件。Linix Shell中可以看到命名管道文件名后面紧跟一个|,可以通过S_ISFIFO宏来检测一个文件是否是命名管道。
下面给出一个通过命名管道通信的一个客户端-服务端程序,实现的功能是客户端在终端输入字符串,写入管道,服务器端从管道读出字符串,并显示在终端上。具体的可以参加《精通Linux C编程一书》
服务器端程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
int main()
{
FILE *fp;
char readbuf[80];
if((fp=fopen(FIFO_FILE,"r"))==NULL)
{
umask(0);
mknod(FIFO_FILE,S_IFIFO|0666,0);
}
else
fclose(fp);
while(1)
{
if((fp=fopen(FIFO_FILE,"r"))==NULL)
{
printf("open fifo failed. \n");
exit(1);
}
if(fgets(readbuf,80,fp)!=NULL)
{
printf("Received string :%s \n", readbuf);
fclose(fp);
}
else
{
if(ferror(fp))
{
printf("read fifo failed.\n");
exit(1);
}
}
}
return 0;
}客户端程序:
除了上面三种方法,Linux还支持Unix System V的IPC机制,消息队列、信号量及共享内存,这几种方法在编程接口和内部实现上都非常像。
(4)消息队列:
int msgget(key_t key, int flag); //创建或打开消息队列
int msgsnd(int msqid, const void* ptr, size_t nbyte, in flag); //向消息队列发送消息
int msgrcv(int msqid, const void* ptr, size_t nbyte, long type in flag); //从消息队列中取出消息
个人感觉消息队列用于进程间的通信是非常灵活和方便的。
(5)信号量:
信号量实际是一个整型计数器,主要用来控制多个进程对共享资源的访问,比如实现关键区。
(6)共享内存:
和Windows中的内存映射文件类似,用共享内存文件进行进程间数据交换的最大好处我认为就是简单,每个进程访问共享内存的时候和访问其他内存没什么区别。不过共享内存有一个问题是,如果多个进程同时对共享内存进行修改,则需要通过信号量等机制进行同步控制。
int shmget(key_t key, int size, int flag); //创建或打开共享内存
void * shmat(int shmid, void *addr, int flag); //将共享内存附加到进程的地址空间中
int shmdt(void *addr); //取消共享内存和进程的地址空间的关系
某种信号相当于某种事件,一般用于内核告诉进程某种事件发生了,进程通过signal函数注册信号的处理函数。我个人体会在用户态中两个进程之间用信号进行进程间通信应该不是一个特别好的方法,限制比较多。
(2)匿名管道:
int pipe(int fdes[2]);//创建匿名管道
管道的都写方法和文件文件读写方法相同
匿名管道一般用在父进程和子进程之间的数据通信,而且匿名管道是在内核中临时存储的,程序运行结束后,就不存在了。
(3)命名管道:任何两个进程之间都可以通过命名管道去通信,命名管道是作为特殊设备文件存储在文件系统中的,当程序运行结束后,它继续存在于文件系统中,除非删除该文件。Linix Shell中可以看到命名管道文件名后面紧跟一个|,可以通过S_ISFIFO宏来检测一个文件是否是命名管道。
下面给出一个通过命名管道通信的一个客户端-服务端程序,实现的功能是客户端在终端输入字符串,写入管道,服务器端从管道读出字符串,并显示在终端上。具体的可以参加《精通Linux C编程一书》
服务器端程序:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/stat.h>
#define FIFO_FILE "MYFIFO"
int main()
{
FILE *fp;
char readbuf[80];
if((fp=fopen(FIFO_FILE,"r"))==NULL)
{
umask(0);
mknod(FIFO_FILE,S_IFIFO|0666,0);
}
else
fclose(fp);
while(1)
{
if((fp=fopen(FIFO_FILE,"r"))==NULL)
{
printf("open fifo failed. \n");
exit(1);
}
if(fgets(readbuf,80,fp)!=NULL)
{
printf("Received string :%s \n", readbuf);
fclose(fp);
}
else
{
if(ferror(fp))
{
printf("read fifo failed.\n");
exit(1);
}
}
}
return 0;
}客户端程序:
#include <stdio.h> #include <stdlib.h> #define FIFO_FILE "MYFIFO" int main(int argc, char *argv[]) { FILE *fp; int i; if(argc<=1) { printf("usage: %s <pathname>\n",argv[0]); exit(1); } if((fp=fopen(FIFO_FILE,"w"))==NULL) { printf("open fifo failed. \n"); exit(1); } for(i=1;i<argc;i++) { if(fputs(argv[i],fp)==EOF) { printf("write fifo error. \n"); exit(1); } if(fputs(" ",fp)==EOF) { printf("write fifo error. \n"); exit(1); } } fclose(fp); return 0; }
除了上面三种方法,Linux还支持Unix System V的IPC机制,消息队列、信号量及共享内存,这几种方法在编程接口和内部实现上都非常像。
(4)消息队列:
int msgget(key_t key, int flag); //创建或打开消息队列
int msgsnd(int msqid, const void* ptr, size_t nbyte, in flag); //向消息队列发送消息
int msgrcv(int msqid, const void* ptr, size_t nbyte, long type in flag); //从消息队列中取出消息
个人感觉消息队列用于进程间的通信是非常灵活和方便的。
(5)信号量:
信号量实际是一个整型计数器,主要用来控制多个进程对共享资源的访问,比如实现关键区。
(6)共享内存:
和Windows中的内存映射文件类似,用共享内存文件进行进程间数据交换的最大好处我认为就是简单,每个进程访问共享内存的时候和访问其他内存没什么区别。不过共享内存有一个问题是,如果多个进程同时对共享内存进行修改,则需要通过信号量等机制进行同步控制。
int shmget(key_t key, int size, int flag); //创建或打开共享内存
void * shmat(int shmid, void *addr, int flag); //将共享内存附加到进程的地址空间中
int shmdt(void *addr); //取消共享内存和进程的地址空间的关系
相关文章推荐
- linux C 编程 之 进程间通信(IPC)
- Linux进程间通信(IPC)编程实践(二) FIFO命名管道
- Linux下网络编程(3)——进程间通信(IPC),共享内存,传递结构体数据
- 【嵌入式Linux C编程】Linux进程间通信——IPC
- UNIX/Linux进程间通信IPC---管道--全总结(实例入门)
- Linux进程间通信(IPC)编程实践(九)System V信号量---封装一个信号量操作的工具集
- Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用
- Linux进程间通信(IPC)编程实践(十一)System V信号量---实现一个先进先出的共享内存shmfifo
- Linux系统编程——进程间通信(System V IPC 对象)
- Linux进程间通信(IPC)编程实践(七)共享内存的使用-System V共享内存(API)
- Linux进程间通信(IPC)编程实践(三) 详解System V消息队列(1)
- linux进程间通信(IPC)机制总结
- Linux进程间通信(IPC)方式总结
- Linux进程间通信(IPC)编程实践(一) 基本概念和匿名管道
- Linux进程间通信(IPC)编程实践(五)消息队列实现回射客户/服务器
- Linux进程间通信(IPC)编程实践(六)共享内存的使用-mmap
- 20155301 滕树晨linux基础——linux进程间通信(IPC)机制总结
- linux基础——linux进程间通信(IPC)机制总结
- Linux进程间通信(IPC)编程实践(十)System V信号量---PV操作经典题目
- Linux进程间通信(IPC)编程实践(四) 详解System V消息队列(2)(msgsnd & msgrcv)