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

Linux程序设计——信号量、共享内存和消息队列

2013年10月14日 ⁄ 综合 ⁄ 共 1916字 ⁄ 字号 评论关闭

1、信号量

多线程程序中总有一部分临界代码,编程人员必须确保只有一个进程可以进入临界代码并拥有对资源的独占式访问权。使用信号量机制可以确保进程之间的并发执行。信号量是一个特殊的变量,只允许对它进行等待(wait)和发送信号(signal)这两种操作,即PV操作:

P——用于等待

V——用于发送信号

》》》PV操作的定义

P(sv)——sv > 0,sv -= 1。sv = 0挂起进程的执行。

V(sv)——如果有其他进程因等待sv而被挂起,则恢复该进程的执行。如果没有进程因等待sv挂起,则sv = sv + 1。

semaphore sv = 1;
loop forever
{
    P(sv);
    critical code section;
    V(sv);
    noncritical code section;
}

2、Linux信号量机制

1)semget

#include <sys.sem.h>
int semget(key_t key, int num_sems, int sem_flags);

作用:创建一个新的信号量或者取得一个已有信号量的键

key:整数值,不相关的进程可以通过它访问同一个信号量

num_sems:需要的信号量数目

num_flags:一组标志,低9个比特是该信号量的权限

成功时返回其他信号量函数将用到的信号量标识符,失败时返回-1。

2)semop

#include <sys/sem.h>
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);

作用:改变信号量的值

sem_id:由semget返回的信号量标识符

struct sembuf
{
    short sem_num; // 信号量编号
    short sem_op;
    short sem_flag;
};

semop调用的一切动作都是一次性完成的,这是为了避免出现因使用多个信号量而可能发生的竞争现象。

3)semctl

#include <sys/sem.h>
int semctl(int sem_id, int sem_num, int command, ...);

作用:直接控制信号量

command参数

SETVAL:用来把信号量初始化为一个已知的值

IPC_RMID:用来删除一个已经无需继续使用的信号量标识符

3、共享内存

共享内存是在两个正在运行的进程之间传递数据的一种非常有效的方式,它允许两个不相关的进程访问同一个逻辑内存。共享内存是由IPC为进程创建的一个特殊的地址空间,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到它们自己的地址空间中。对共享内存访问的同步控制必须由程序员来操作。

1)shmget

#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

作用:创建共享内存

key:为共享内存段命名

size:以字节为单位指定需要共享的内存容量

成功时,返回一个共享内存标识符,失败返回-1。

2)shmat

#include <sys/shm.h>
void *shmat(int shm_id, const void *shm_addr, int shmflg);

作用:将共享内存连接到进程的内存空间中

shm_addr:共享内存连接到当前进程中的地址位置

3)shmdt

#include <sys/shm.h>
int shmdt(const void *shm_addr);

作用:将共享内存从当前进程分离

4)shmctl

#include <sys/shm.h>
int shmctl(int shm_id, int command, struct shmid_ds *buf);

作用:控制共享内存

4、消息队列

消息队列提供一种在两个不相关的进程之间传递数据的相当简单且有效的方法。消息队列独立于发送和接收进程存在,消除了同步命名管道的打开和关闭时可能产生的一些困难。

#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
int msgget(key_t key, int msgflg);
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);

1)msgget

作用:创建和访问一个消息队列

2)msgsnd

作用:把消息添加到消息队列中

3)msgrcv

作用:从一个消息队列中获取消息

4)msgctl

作用:控制消息队列


总结:本文主要介绍进程间通信的三种机制,包括信号量、共享内存和消息队列。并介绍相关操作的函数接口。

抱歉!评论已关闭.