#深入理解System V原理
深入理解System V原理1. sysem v消息队列------------------------------------------------ struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
struct msg *msg_frist /* ptr to first message on queue */
struct msg *msg_last /* ptr to last message on queue */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
int msgget(key_t key,int oflag);
这个函数的参数和返回值就在这里,不在累赘。 struct ipc_perm
{
key_t key; /*ipc的key值*/
uid_t uid; /*共享内存所有者的有效用户ID */
gid_t gid; /* 共享内存所有者所属组的有效组ID*/
uid_t cuid; /* 共享内存创建 者的有效用户ID*/
gid_t cgid; /* 共享内存创建者所属组的有效组ID*/
unsigned short mode; /* Permissions + SHM_DEST和SHM_LOCKED标志*/
unsignedshort seq; /* 序列号*/
};
其中uid和cuid,gid和cgid会根据当前进程的用户和用户组ID进行初始化 int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
ssize_t msgrcv(int msqid,void *msgp,long msgtyp,int msgflg);
这两个函数密不可分,所以我放在一起说,看名字就知道一个是发送消息,一个是接受消息。 struct mesg
{
long mesg_tpye;
char mesg_date[BUF_SIZE];
};
在自定义的结构体的时候要注意,第一个成员一定要是long类型的tpye成员,用于存放消息类型。用我自定义的结构体为例子,msgsnd的第二个应该为mesg的指针,第三个应该为strlen(mesg_date)+1。那么来一个更通用的列子吧。 struct mesg
{
long mesg_tpye;
int mesg_short;
char mesg_date[BUF_SIZE];
};
在这里有两个数据需要传递,那么长度应该怎么写呢?可以是sizeof(mesg) - sizeof(long); 在msgrcv中有一个type,也需要注意。 int msgctl(int msqid,int cmd,struct msqid_ds *buf);
cmd一共有三个参数:
2. sysem v信号量------------------------------------------------ struct semid_ds {
struct ipc_perm sem_perm; /* Ownership and permissions */
time_t sem_otime; /* Last semop time */
time_t sem_ctime; /* Last change time */
unsigned long sem_nsems; /* No. of semaphores in set */
struct sem *sem_base; /* ptr to array of sem */
};
这里面有一个新的成员,值得一提sem_nsems它表示信号量数组的元素的个数。sem_base结构体指针实际上其实是不存在的(就算存在也是指向内核的一部分区域)。 struct sem{
ushort_t semval; /*sem value,nonnegative */
short sempid /*pid of last successful semop(),SETVAL,SETALL */
ushort_t semncnt; /*awating semval >current value */
ushort_t semzcnt; /*awating semval = 0 */
}
其中semcnt 是等待其值增长的进程数计数,semzcnt是等待其值变0的进程数计数; int semget(key_t key,int nsems,int semflg);
这个函数既可以创建信号量,也可以访问信号量。在创建信号量时候,nsems为要创建的信号量的数量,semflag为其权限:SEM_R和SEM_A分别表示读和改还可以与常见的ipc权限进行按或位。 int semop(int semid,struct sembuf *sops,size_t nsops);
这个函数用与操作sem信号量。 struct sembuf{
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
其中sem_num 用于指定操作第几个信号量, op是操作数, 通常是+1 -1分别对应pv操作。 int semctl(int semid,int semnum,int cmd,...);
...对应union semun arg* union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT,IPC_SET */
unsigned short *array; /* Array for GETALL,SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */
};
这个公用体在需要在程序中显示的申明! 从信号量集上检索semid_ds结构,并存到semun联合体参数的成员buf的地址中 IPC_SET 设置一个信号量集合的semid_ds结构中ipc_perm域的值,并从semun的buf中取出值 IPC_RMID 从内核中删除信号量集合 GETALL 从信号量集合中获得所有信号量的值,并把其整数值存到semun联合体成员的一个指针数组中 GETNCNT 返回当前等待资源的进程个数 GETPID 返回最后一个执行系统调用semop()进程的PID GETVAL 返回信号量集合内单个信号量的值 GETZCNT 返回当前等待100%资源利用的进程个数 SETALL 与GETALL正好相反 SETVAL 用联合体中val成员的值设置信号量集合中单个信号量的值
3. sysem v共享内存------------------------------------------------ struct shmid_ds {
struct ipc_perm shm_perm; /* Ownership and permissions */
size_t shm_segsz; /* Size of segment (bytes) */
time_t shm_atime; /* Last attach time */
time_t shm_dtime; /* Last detach time */
time_t shm_ctime; /* Last change time */
pid_t shm_cpid; /* PID of creator */
pid_t shm_lpid; /* PID of last shmat(2)/shmdt(2) */
shmatt_t shm_nattch; /* No. of current attaches */
...
};
除了有一个shm_nattch之外,其他成员都是多次使用。 void *shmat(int shmid,const void *shmaddr,int shmflg);
int shmdt(const void *shmaddr);
这两个函数分别用于附接和断开进程的地址空间。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |