现在的位置: 首页 > 综合 > 正文

linux下的进程间通讯

2012年06月04日 ⁄ 综合 ⁄ 共 5963字 ⁄ 字号 评论关闭

1.进程通讯的几种不同形式

1)消息传递:管道、FIFO、消息队列

2)同步:互斥锁、条件变量、读写锁、文件与记录锁、信号灯

3)共享内存区:匿名共享内存区、有名共享内存区

4)远程过程调用:Solaris门、sun RPC

 

2.进程间共享信息的方法

 

 

 

3.IPC对象的持续性

1)随进程的持续性

一直存在到打开该对像的最后一个进程关闭该对象;

如:管道和FIFO.

2)随内核的持续性

一直存在到内核重新自举或显式删除该对象为止;

如:System V消息队列、信号灯和共享内存区;

      Posix消息队列、信号灯和共享内存区;

3)随文件的持续性

一直存在到显式删除该对象为止;

如:Posix消息队列、信号灯和共享内存区,使用映射文件实现时;

 

 

 

 

 

 4. 无名管道:只能用于fork之间进程的操作。

 

命令使用:
cut -f1 -d: </etc/group | sort
/etc/group作为cut命令的输入,使用重定向技术;
cut命令的输出,作为sort的输入,使用管道技术;

 

相关函数:

头文件:#include <unistd.h>

int pipe(int filedes[2]);
功能:创建管道;
参数:filedes[0]        OUT        从管道读数据描述符;
         filedes[1]        OUT        向管道写数据描述符;    
返回:0,执行成功;
     -1,执行失败;设置errno。
说明:filedes[0]用O_RDONLY方式打开;
      filedes[1]用O_WRONLY方式打开;
      使用结束时,要确保两个文件描述符全部关闭。使用close();
      使用时,一个进程读管道数据,另一个进程写管道数据;
      当向管道写数据时,需要关闭读文件描述符。同时,对应的读管道数据的进程要
      关闭写数据文件描述符。

 

头文件:#include <stdio.h>

FILE *popen(const char *command, const char *mode);
功能:创建管道,然后fork一个子进程,接着执行一个exec调用,调用/bin/sh -c执行保存在command
      中的命令字符串。
参数:command       IN        指向命令字符串的指针;
      mode         IN        r(or)w;    
返回:用于读写的文件流,执行成功;
      NULL,执行失败;设置errno。
说明:mode = r,popen返回的FILE流指针用于读command的标准输出;
      mode = w,popen返回的FILE流指针用于向command的标准输入写数据。

 

int pclose(FILE *stream);
功能:关闭I/O流。
参数:stream       IN        指定的文件流;
返回:退出状态,执行成功;
      -1,执行失败。
说明:

 

 

 

 

 

 

 

 

/******************************************进程通讯

****************************************************/
/*无名管道:只能用于fork之间进程的操作。
命令使用:
cut -f1 -d: </etc/group | sort
/etc/group作为cut命令的输入,使用重定向技术;
cut命令的输出,作为sort的输入,使用管道技术;

相关函数:
头文件:#include <unistd.h>
int pipe(int filedes[2]);
功能:创建管道;
参数:filedes[0]        OUT        从管道读数据描述符;
      filedes[1]        OUT        向管道写数据描述符;    
返回:0,执行成功;
     -1,执行失败;设置errno。
说明:filedes[0]用O_RDONLY方式打开;
      filedes[1]用O_WRONLY方式打开;
      使用结束时,要确保两个文件描述符全部关闭。使用close();
      使用时,一个进程读管道数据,另一个进程写管道数据;
      当向管道写数据时,需要关闭读文件描述符。同时,对应的读管道数据的进程要
      关闭写数据文件描述符。

头文件:#include <stdio.h>
FILE *popen(const char *command, const char *mode);
功能:创建管道,然后fork一个子进程,接着执行一个exec调用,调用/bin/sh -c执行保存在command
      中的命令字符串。
参数:command       IN        指向命令字符串的指针;
      mode         IN        r(or)w;    
返回:用于读写的文件流,执行成功;
      NULL,执行失败;设置errno。
说明:mode = r,popen返回的FILE流指针用于读command的标准输出;
      mode = w,popen返回的FILE流指针用于向command的标准输入写数据。

int pclose(FILE *stream);
功能:关闭I/O流。
参数:stream       IN        指定的文件流;
返回:退出状态,执行成功;
      -1,执行失败。
说明:
*/

/*有名管道(FIFO):能用于无关进程之间的操作。
命令使用:
mkfifo [option] name
mkfifo -m 600 fifo1
创建一个名为fifo的管道;
相关函数:
头文件:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:用mode指定的权限位创建一个名为pathname的FIFO。
参数:pathname     IN   FIFO名字
      mode         IN   FIFO的权限
返回:0,执行成功;
     -1,执行失败;
说明:mode中的值会被进程中的umask修改。
      修改规则为mode&~umask
      可能返回的错误值:EACCESS、EECIST、ENAMETOOLONG、ENOENT、ENOSPC、ENOTDIR、EROFS。

打开、读写、删除、读取、写入操作等同与对文件操作;
使用函数open、close、unlink、read、write。
注意:FIFO两端都必须在使用之前打开;
      打开时通过使用O_NONBLOCK可以使读写操作立即返回。

相关问题:
如何获取和设置进程的umask。
答案:通过umask函数。具体参照本文件中umask函数的说明。

/*********************************IPC*******************************/
在创建一个system v ipc对象的时候,进程的umask不会修改对象的访问权限;
如果没有设置访问权限,模式为0,所有人都没有对它的读写权。

/*共享内存
命令:ipcs -m 打印共享内存;
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
函数:
int shmget(key_t key, int size, int flags);
功能:创建一个新的共享内存段,或者返回key指定的共享内存段的标示。
参数:key     IN   共享段关键字.
      size    IN   共享段的大小.
      flags   IN   创建标志.
返回:段标识符,执行成功
      -1,执行失败;
说明:key:IPC_PRIVATE,系统随机指定一个键值;
          也可以有ftok()函数生成;
          也可以自己在头文件中定义该键值。
      size:创建共享段的大小,受处理器本身页大小的限制。
           INTEL 4KB,ALPHA 8KB。
      flag:IPC_CREAT、IPC_EXCL和一组权限位(模式)按位”或“的结果。
           IPC_EXCL:当段已经存在时,返回-1,而不是段标示符;
           IPC_CREAT:如果没有和KEY关联的段就创建一个新段。

char *shmat(int shmid, char *shmaddr, int flags);
功能:附加共享内存段到调用进程地址空间中。
参数:shmid      IN   共享段标识符.
      shmaddr    IN   共享段的进程映像地址,一般设置为0由进程自动分配。
      flags      IN   读写标志.SHM_RDONLY,该段只读,默认可读写。
返回:附加段地址,执行成功
      -1,执行失败;
说明:
int shmds(char *shmaddr);
功能:将进程地址空间中的附加内存共享段分离出去。
参数:
      shmaddr    IN   shmat的返回值。
返回:0,执行成功
      -1,执行失败;
说明:
*/

/*消息队列
命令:ipcs -q
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
函数:
int msgget(key_t key, int flags);
功能:返回新的或已有队列的队列ID。
参数:key     IN   消息队列关键字.
      flags   IN   创建标志。
返回:0,执行成功
      -1,执行失败;
说明:key:IPC_PRIVATE,系统随机指定一个键值;
          也可以自己在头文件中定义该键值。
      flag:IPC_CREAT和一组权限位(模式)按位”或“的结果。
           IPC_CREAT:如果没有和KEY关联的段就创建一个新段。

int msgsnd(int msqid, const void *ptr, size_t nbytes, int flags);
功能:向队列中写入消息。
参数:msqid     IN   消息队列id号。
   ptr    IN  指向msgbuf结构的指针。
   nbytes    IN  添加消息的字节数
      flags    IN   创建标志。
返回:0,执行成功
      -1,执行失败;设置错误变量为EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
说明:struct msgbuf{
      long mtype;/*任何大于0的值*/
      char mtext[1];/*长度为nbytes-末尾的null字符*/
   };
   消息不应该以null结尾;
  
   flag:0,          阻塞方式;
      IPC_NOWAIT, 非阻塞方式;

int msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flags);
功能:删除从队列返回的消息。
参数:msqid     IN   消息队列id号。
   ptr    IN  指向msgbuf结构的指针。
   nbytes    IN  读取消息的字节数.
   type      IN   决定返回哪个消息。
      flags    IN   创建标志。
返回:0,执行成功
      -1,执行失败;设置错误变量为EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
说明:type:0,返回队列中的第一条消息;
        大于0,返回msg_type等于type的第一条消息;
        小于0,返回msg_type为小于等于type绝对值的最小值的第一条消息;  
   flag:MSG_NOERROR, 返回的消息比nbytes字节多,截断到nbytes字节;
         否则返回-1,设置errno值为E2BIG,消息仍旧在队列中。
      IPC_NOWAIT, 没有指定类型的消息,立即返回,设置ENOMSG;
      否则阻塞。
     
int msgctl(int msgid, int cmd, struct msgid_ds *buf);
功能:根据cmd不同值进行不同的操作。
参数:msqid     IN   消息队列id号。
   cmd       IN   。
      buf      OUT  获取队列的msgid_ds结构。
返回:0,执行成功
      -1,执行失败;设置错误变量为EAGAIN、EACCES、EFAULT、EIDRM、EINTR、EINVAL、ENOMEM。
说明:cmd:IPC_RMID,删除队列msgid;
           IPC_STAT,用队列的msgid_ds结构填充buf,并可以查看队列的内容而不会删除任何消息。
           IPC_SET,可以改变队列的UID、GID、访问模式和队列的最大字节数。
*/
/*信号灯
命令:ipcs -s
头文件:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
函数:
int semget(key_t key, int nsems, int flags);
功能:同另外两种IPC对象。
int semop(int semid, struct sembuf *semops, unsigned nops);
功能:
参数:
返回:
说明:struct sembuf{
          short sem_num;
          short sem_op;
          short sem_flg;
          }
      sem_num是信号灯的编号,其值从0到nsems-1;
      sem_op是执行的操作;为正,信号灯控制的资源被释放,而且信号灯的值增加;
                          为负,调用进程表示它将等待直到受控资源被释放,此时信号灯的值减小而资源被调用进程加锁;
                          为0, 调用进程阻塞直到信号灯变为0;如果信号灯已经是0,调用立即返回。
      sem_flg调整semop的行为;
int semctl(int semid, int semnum, int cmd, union semun arg);
功能:
参数:
返回:
说明:
*/

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/apn172/archive/2010/12/20/6087543.aspx

抱歉!评论已关闭.