进程间通信(IPC)——信号量、共享内存、消息队列

来源:互联网 发布:淘宝分销平台下载 编辑:程序博客网 时间:2024/05/18 14:27
IPC(Inter-Process Communication)主要手段:信号量、共享内存、消息队列。另外还有:管道、Socket等。
非网络IPC和网络IPC(Socket API)都是需要的。
IPC按形式上分可分成4种不同的IPC形式:
1)消息传递(管道、FIFO命名管道、消息队列)
2)同步(互斥量、条件变量、读写锁、文件和记录锁、信号量)
3)共享内存(匿名的和具名的)
4)远过程调用(Solaris门和SunRPC)

ipcs -s:观察信号量信息。文件:/proc/sysvipc/sem
ipcs -m:观察共享内存信息。文件:/proc/sysvipc/shm
ipcs -q:观察消息队列信息。文件:/proc/sysvipc/msg

 信号量,是一个特殊变量,只能对它进行初始化操作、PV操作、删除操作。主要是PV操作(又称wait、signal或者up、down)。信号量是著名荷兰计算机科学家Dijkstra(单源最短路径、goto有害,你懂的)提出来的。

信号量函数介绍:

    #include <sys/sem.h>//通常包含<sys/types.h>和<sys/ipc.h>  
    /*****信号量涉及到三个函数************/  
    /*****
    key:整型值,不相关进程通过它来访问同一信号量。
    num_sems:参数指定需要的信号量数目,几乎总是取1
    sem_flags:一组标志,一般取 IPC_CREAT|0644
    返回值:信号量的sem_id
    *****/  
    int semget(key_t key,int num_sems,int sem_flags);  
      
    /*****
    sem_ops:      
    *****/  
    struct sembuf  
    {  
        short sem_num;//信号量编号,除非使用一组信号量,否则取值为0  
        short sem_op;//PV操作,1为P操作,-1为V操作  
        short sem_flg;//设它为SEM_UNDO是个好习惯  
    }  
    //num_sem_ops:一般设为 1(???)  
    int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_ops);      
      
    /*****
    sem_num:信号量编号,除非使用一组信号量,否则取值为0
    command:将要采取的操作,例如,SETVAL初始化,IPC_RMID删除信号量
    第四个参数:union semun联合体,X/Open指出,semun联合体由程序员自
    己定义,他至少应该是下列结构
    *****/  
    union semun  
    {  
        int val;//初始化时,设置的信号量初值  
        struct semid_ds *buf;  
        unsigned short *array;  
    }  
    int semctl(int sem_id,int sem_num,int command,...);  

共享内存函数介绍:
    #include <sys/shm.h>//通常包含<sys/types.h>和<sys/ipc.h>  
    /********************共享内存包含四个函数**************************/  
    /*****
    key:整型值,为共享内存段命名
    size:共享内存大小,字节数
    shmflg:一组标志,一般取 IPC_CREAT|0644(权限标识)
    返回值:成功返回共享内存id-shm_id,失败-1
    *****/  
    int shmget(key_t key,size_t size,int shmflg);  
      
    /*****
    作用:将共享内存连接到一个进程的地址空间
    shm_addr:共享内存连接到当前进程中的地址为止,通常为void*,表示让
    系统来选择共享内存出现的地址。
    shmflg:其中两个可能取值有,SHM_RND和SHM_RDONLY。通常设为 0
    返回值:成功返回指向共享内存第一个字节指针,失败-1
    *****/  
    int *shmat(int shm_id,const void *shm_addr,int shmflg);  
      
    /****将共享内存从当前进程中分离,成功返回0,失败-1*****/  
    int shmdt(const void *shm_addr);  
      
    /*****共享内存控制函数******/  
    struct shmid_ds  
    {  
        uid_t shm_perm.uid;  
        uid_t shm_perm.gid;  
        mode_t shm_perm.mode;  
    }  
    /*******
    command:采取的动作,取三个值(IPC_STAT,IPC_SET,IPC_RMID删除共享内存段)
    buf:指向包含共享内存模式和访问权限的结构
    ********/  
    int shmctl(int shm_id,int command,struct shmid_ds *buf);  

消息队列函数:
    #include <sys/msg.h>////通常包含<sys/types.h>和<sys/ipc.h>  
    /*******消息队列涉及四个函数**********/  
    /*
    key:键值
    msgflg:权限标识,通常设为IPC_CREAT|0644
    返回值:成功,消息队列id;失败-1
    */  
    int msgget(key_t key,int msgflg);  
      
    struct msqid_ds  
    {  
        uid_t msg_perm.uid;  
        uid_t msg_perm.gid;  
        mode_t msg_perm.mode;  
    }  
    /*****
    command:要采取的动作,eg,
    IPC_STAT,把msqid结构中的数据设置为消息队列的当前关联值。
    IPC_SET,如果进程有足够的权限,就把消息队列的当前关联值设为msqid_ds结构中给出的值
    IPC_RMID,删除消息队列
    *****/  
    int msgctl(int msqid,int cmd,struct msqid_ds *buf);  
    struct my_message//自定义消息  
    {  
        long int message_type;  
        /* 要发送的消息 */  
    }  
    /***
    msg_ptr:消息指针,消息自己定义
    msg_sz:消息长度,不包括long成员长度
    msgtype:消息类型long型
    msgflg:控制当前消息队列满或者队列消息到达系统范围的限制时,将要发生的事情。IPC_NOWAIT非阻塞标志,0阻塞标志。
    ***/  
    int msgrcv(int msqid,void *msg_ptr,size_t msg_sz,long int msgtype,int msgflg);  
    /*同上*/  
    int msgsnd(int msqid,const void *msg_ptr,size_t msg_sz,int msgflg); 

原创粉丝点击