Linux进程间通信_IPC方法综述
来源:互联网 发布:女生帆布鞋淘宝 编辑:程序博客网 时间:2024/06/06 07:02
Outline
- 1.
pipe使用框架 - 2.
fifo使用框架 - 3.
file lock使用框架 -
4.semaphore使用框架
-
5.shared memory使用框架
-
6.memory mapped file使用框架
-
7.unix socket使用框架
=============================================================
1. pipe使用框架:
实现 "ls | wc -l"
int pipefd[2];
pipe(pipefd);
if(!fork()) {
close(pipefd[0]);
dup2(pipefd[1], 1);
execlp("ls", "ls", NULL);
exit(0);
} else {
wait(NULL);
close(pipefd[1]);
dup2(pipefd[0], 0);
execlp("wc", "wc", "-l", NULL);
exit(0);
}
注:一般pipe大小为10K
2. fifo使用框架
实现echo writer reader,即writer在fifo中写,reader在fifo中读并回显
writer:
mknod("fifoname", S_FIFO | 0666, 0);
fd = open("fifoname", O_WRONLY);
write(fd, input, sizeof(input));
//unlink("fifoname");
reader:
fd = open("fifoname", O_RDONLY);
read(fd, output, sizeof(output));
printf("%s", output);
注意:若reader先关闭,则writer在执行write时收到sigpipe信号;反之,reader执行reader时返回0.
open在没有读者/写者时候,都见先阻塞,直到第一个读者/写者到来.
3. file lock使用框架
所谓file lock,就是对文件加读/写锁,读写锁的原则是一个文件可以有多个读者(没有写者),但是只能有一个写者(没有读者)。具体到程序即,获取多个读锁不会阻塞,但是获取多个写锁会阻塞;有读者时,获取写锁会阻塞;有写者时,获取读锁会阻塞。
下面这个例子,有参数时,给文件加读锁;无参数时,给文件加写锁。按回车后,释放锁。
- /*
- * =====================================================================================
- *
- * Filename: rw_locks.c
- *
- * Description:
- *
- * Version: 1.0
- * Created: 08/10/11 13:14:57
- * Revision: none
- * Compiler: gcc
- *
- * Author: YOUR NAME(),
- * Company:
- *
- * =====================================================================================
- */
- #include <stdio.h>
- #include <error.h>
- #include <fcntl.h>
- #include <unistd.h>
- int main(int argc, char*argv[])
- {
- int fd;
- struct flock flock;
- flock.l_type = F_WRLCK; //锁的模式必须与文件打开模式显适应
- flock.l_whence = SEEK_SET;
- flock.l_start = 0;
- flock.l_len = 0;
- flock.l_pid = getpid();
- fd = open("tt", O_RDWR);
- if (fd== -1) {
- perror("open file error");
- return -1;
- }
- if(argc> 1)
- flock.l_type = F_RDLCK;
- printf("Trying to obtain a %s lock!\n",
- flock.l_type == F_RDLCK ? "read_lock" : "write lock");
- if (fcntl(fd, F_SETLKW,&flock) == -1){
- perror("fcntl error");
- return -1;
- }
- printf("Got a lock!\n");
- printf("Press <RETURN> to release the lock\n");
- getchar();
- flock.l_type = F_UNLCK; //UNLOCK
- if (fcntl(fd, F_SETLK,&flock)){ //F_SETLK 用于解锁,也可用于加锁,但与F_SETLKW的区别在于不会被阻塞,立即返回-1
- perror("fcntl error");
- return -1;
- }
- printf("Lock released!\n");
- close(fd);
- return 0;
- }
3. mseeage queue使用框架
ftok("filename", 'A') //存在的文件名加任意int产生key
msgget //IPC_CREAT
msgsnd / msgrcv
//msgctl(id, IPC_RMID, NULL)
注:可存在多个读写者
4. semaphore使用框架
semapore中要特别注意的一点是semaphore set创建以后需要进行初始化(semop),在初始化完成前(通过检查semid_ds中的sem_otime域),其他使用该set的进程需要等待
- #include <stdio.h>
- #include <error.h>
- #include <unistd.h>
- #include <sys/sem.h>
- #include <sys/ipc.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #define SEMNUM 1
- int main(int argc, char*argv[])
- {
- key_t key;
- int semid;
- struct sembuf buf = {0, 1, 0};
- key = ftok("tt",'A');
- if (key== -1) {
- perror("ftok error");
- return -1;
- }
- semid = semget(key, SEMNUM, IPC_CREAT| IPC_EXCL | 0666);
- if (semid== -1) {
- perror("semget error");
- return -1;
- }
- puts("initialize the semaphore set...");
- puts("press <RETURN> to continue");
- getchar();
- for (buf.sem_num= 0; buf.sem_num< SEMNUM; buf.sem_num++){
- if (semop(semid,&buf, 1)== -1) {
- perror("semop error");
- semctl(semid, 0, IPC_RMID);
- return -1;
- }
- }
- //-----------------------------------
-
- buf.sem_num = 0;
- buf.sem_op = -1;
- buf.sem_flg = 0;
- puts("Acquire a resource");
- if (semop(semid,&buf, 1)== -1) {
- perror("semop error");
- return -1;
- }
- puts("Resource locked");
- puts("Press <RETURN> to unlock");
- getchar();
-
- buf.sem_op = 1;
- if (semop(semid,&buf, 1)== -1) {
- perror("semop error");
- return -1;
- }
- puts("Resource unlocked");
- puts("Press <RETURN> to destroy");
- getchar();
- if (semctl(semid, 0, IPC_RMID)== -1) {
- perror("semctl error");
- return -1;
- }
- return 0;
- }
- #include <stdio.h>
- #include <error.h>
- #include <sys/sem.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <errno.h>
- int main()
- {
- key_t key;
- int semid;
- union semun{
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- struct seminfo *__buf;
- }arg;
- struct sembuf buf;
- struct semid_ds ds;
-
- key = ftok("tt",'A');
- if (key== -1) {
- perror("ftok error");
- return -1;
- }
- semid = semget(key, 1, IPC_CREAT| IPC_EXCL );
-
- puts("waiting for initialization");
- if (semid== -1) {
- if (errno== EEXIST){
- while(1){
- semid = semget(key, 1, 0666);
- if (semid < 0){
- perror("semget error");
- return -1;
- }
-
- arg.buf = &ds;
- if (semctl(semid, 0, IPC_STAT, arg)== -1) {
- perror("semctl1 error");
- //return-1;
- }
-
- if (arg.buf->sem_otime!= 0)
- break;
- }
- } else{
- perror("semget2 error");
- return -1;
- }
- }
- puts("initialization is done");
- puts("locking resource");
- buf.sem_num = 0;
- buf.sem_op = -1;
- buf.sem_flg = 0;
- if (semop(semid,&buf, 1)== -1) {
- perror("semop error");
- return -1;
- }
- puts("Resource locked");
- puts("press <RETURN> to unlock");
- getchar();
- buf.sem_op = 1;
- if (semop(semid,&buf, 1)== -1) {
- perror("semop error");
- return -1;
- }
- puts("Resource unlocked");
- return 0;
- }
5. shared memory使用框架
ftok
shmget //IPC_CREAT
data = shmat(id, (void *)0, 0)
//do sth with the return pointer
shmdt
//shmctl(id, IPC_RMID, NULL)
6. memory mapped file使用框架
open
data = mmap((void *)0, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)
read / write
munmap(data, statbuf.st_size)
注意,若使用MAP_PRIVATE则各进程分别获取file的一份拷贝,并且最终修改不会写入文件中
7. unix socket使用框架
sockaddr_un local;
local.sun_family = AF_UNIX;
strcpy(local.sun_path, "/a/b/c")
server端
fd = socket(...)
unlink("a/b/c")
bind
listen
newfd = accept
recv / send
close
client端
fd=socket(...)
unlink("/a/b/c")
connect
send / recv
close
FROM: http://blog.chinaunix.net/uid-21084809-id-2150056.html
FROM: http://blog.chinaunix.net/uid-21084809-id-2150056.html
0 0
- Linux进程间通信_IPC方法综述
- Linux进程间通信_IPC机制
- Linux进程间通信_IPC机制的深入理解2
- linux进程间通信综述
- linux 进程间通信综述
- Linux进程间通信(IPC)之综述
- Linux进程间通信方法
- linux进程间通信方法
- linux进程间通信方法
- linux进程间通信方法
- 【Linux】Linux进程间通信的方法
- Linux进程间通信的方法
- Linux进程间通信的方法
- linux 进程间通信方法综合分析
- linux进程间通信方法汇总
- linux进程间通信的方法
- Linux进程通信方法--管道
- 进程间通信与线程间通信 . windows下多线程通信方法 Linux 多线程通信
- Windows 10 , 在路上 You are already an expert !;
- win8系统 ps不能直接拖入图片的问题!解决方法
- 携程崩溃:原因为何,谁该反思
- Android - 多语言自动适配
- centos 卸载自带的 java
- Linux进程间通信_IPC方法综述
- .htaccess技巧: URL重写(Rewrite)与重定向(Redirect)
- GUID与MD5加密
- PDF转换成TXT的疑惑
- VB.NET 创建打印机选择列表
- xbmc从onEvent到onkey创建CKey对象的过程
- java 工厂模式
- OV7725+广州创龙OMAPL138开发板调试(从选型到出图像)
- 中科院大牛博士是如何进行文献检索和阅读(好习惯受益终生)(转载)