EINVAL:参数size小于SHMMIN或大于SHMMAX
EEXIST:预建立key所指的共享内存,但已经存在
EIDRM:参数key所指的共享内存已经删除
ENOSPC:超过了系统允许建立的共享内存的最大值(SHMALL)
ENOENT:参数key所指的共享内存不存在,而参数shmflg未设IPC_CREAT位
EACCES:没有权限
ENOMEM:核心内存不足
sys/shm.h
中有关于 shmat
的原型声明
/* Attach shared memory segment. */
extern void *shmat (int __shmid, __const void *__shmaddr, int __shmflg)
__THROW;
连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问
__shmid
共享内存标识符
__shmaddr
指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置
__shmflg
SHM_RDONLY:为只读模式,其他为读写模式
如果成功则返回附加好的共享内存地址,如果出错,则返回-1,错误原因存于error中
Tip: fork后子进程继承已连接的共享内存地址;exec后该子进程与已连接的共享内存地址自动脱离(detach);进程结束后,已连接的共享内存地址会自动脱离(detach)
有以下几种错误
EACCES:无权限以指定方式连接共享内存
EINVAL:无效的参数shmid或shmaddr
ENOMEM:核心内存不足
sys/sem.h
中有关于 semget
的原型声明
/* Get semaphore. */
extern int semget (key_t __key, int __nsems, int __semflg) __THROW;
得到一个信号量集标识符或创建一个信号量集对象并返回信号量集标识符
__key
通常要求此值来源于ftok返回的IPC键值
__nsems
创建信号量集中信号量的个数,该参数只在创建信号量集时有效
__semflg
IPC_CREAT:当 semflg&IPC_CREAT
为真时,如果内核中不存在键值与key相等的信号量集,则新建一个信号量集;如果存在这样的信号量集,返回此信号量集的标识符;IPC_CREAT|IPC_EXCL
:如果内核中不存在键值与key相等的信号量集,则新建一个消息队列;如果存在这样的信号量集则报错
如果成功则返回信号量集的标识符,如果失败则返回-1,错误原因存于error中
有以下几种错误
EACCESS:没有权限
EEXIST:信号量集已经存在,无法创建
EIDRM:信号量集已经删除
ENOENT:信号量集不存在,同时semflg没有设置IPC_CREAT标志
ENOMEM:没有足够的内存创建新的信号量集
ENOSPC:超出限制
sys/sem.h
中有关于 semop
的原型声明
/* Operate on semaphore. */
extern int semop (int __semid, struct sembuf *__sops, size_t __nsops) __THROW;
对信号量集标识符为semid中的一个或多个信号量进行P操作或V操作
__semid
信号量集标识符
__sops
sembuf 结构体的指针,这个结构体里存放着操作的内容,结构体相关内容可以参看前面的说明
__nsops
进行操作信号量的个数,即sops结构变量的个数,需大于或等于1。最常见设置此值等于1,只完成对一个信号量的操作
如果成功则返回信号量集的标识,如果出错,则返回-1,错误原因存于error中
有以下几种错误
E2BIG:一次对信号量个数的操作超过了系统限制
EACCESS:权限不够
EAGAIN:使用了IPC_NOWAIT,但操作不能继续进行
EFAULT:sops指向的地址无效
EIDRM:信号量集已经删除
EINTR:当睡眠时接收到其他信号
EINVAL:信号量集不存在,或者semid无效
ENOMEM:使用了SEM_UNDO,但无足够的内存创建所需的数据结构
ERANGE:信号量值超出范围
sys/shm.h
中有关于 shmdt
的原型声明
/* Detach shared memory segment. */
extern int shmdt (__const void *__shmaddr) __THROW;
与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存
__shmaddr
连接的共享内存的起始地址
成功则返回0,出错则返回-1,错误原因存于error中
本函数调用并不删除所指定的共享内存区,而只是将先前用shmat函数连接(attach)好的共享内存脱离(detach)目前的进程
有以下几种错误
EINVAL:无效的参数shmaddr
sys/sem.h
中有关于 semctl
的原型声明
/* Semaphore control operation. */
extern int semctl (int __semid, int __semnum, int __cmd, ...) __THROW;
在指定的信号集或信号集内的某个信号上执行控制操作
__semid
信号量集标识符
__semnum
信号量集数组上的下标,表示某一个信号量
__cmd
可以取以下的宏
/* Commands for `semctl'. */
#define GETPID 11 /* get sempid */
#define GETVAL 12 /* get semval */
#define GETALL 13 /* get all semval's */
#define GETNCNT 14 /* get semncnt */
#define GETZCNT 15 /* get semzcnt */
#define SETVAL 16 /* set semval */
#define SETALL 17 /* set all semval's */
bits/sem.h
中有关于 sembuf 的说明
/* The user should define a union like the following to use it for arguments
for `semctl'.
union semun
{
int val; <= value for SETVAL
struct semid_ds *buf; <= buffer for IPC_STAT & IPC_SET
unsigned short int *array; <= array for GETALL & SETALL
struct seminfo *__buf; <= buffer for IPC_INFO
};
Previous versions of this file used to define this union but this is
incorrect. One can test the macro _SEM_SEMUN_UNDEFINED to see whether
one must define the union or not. */
这是一个共用体,用作 semctl 的参数,不同的共用体成员可以用于不同的情景中
bits/sem.h
中有关于 semid_ds 的说明
/* Data structure describing a set of semaphores. */
struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
__time_t sem_otime; /* last semop() time */
unsigned long int __unused1;
__time_t sem_ctime; /* last time changed by semctl() */
unsigned long int __unused2;
unsigned long int sem_nsems; /* number of semaphores in set */
unsigned long int __unused3;
unsigned long int __unused4;
};
这个结构体的指针可以在semctl中作为参数获取信号量的信息
bits/sem.h
中有关于 seminfo 结构体的说明
struct seminfo
{
int semmap;
int semmni;
int semmns;
int semmnu;
int semmsl;
int semopm;
int semume;
int semusz;
int semvmx;
int semaem;
};
这个结构体的指针可以在semctl中作为参数获取信号量的信息
sys/shm.h
中有关于 shmctl 的原型声明
/* Shared memory control operation. */
extern int shmctl (int __shmid, int __cmd, struct shmid_ds *__buf) __THROW;
完成对共享内存的控制
__shmid
共享内存标识符
__cmd
IPC_STAT
:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中;IPC_SET
:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内;IPC_RMID
:删除这片共享内存
__buf
共享内存管理结构体指针
如果成功则返回0,如果出错则返回-1,错误原因存于error中
可能的错误有
EACCESS:参数cmd为IPC_STAT,确无权限读取该共享内存
EFAULT:参数buf指向无效的内存地址
EIDRM:标识符为msqid的共享内存已被删除
EINVAL:无效的参数cmd或shmid
EPERM:参数cmd为IPC_SET或IPC_RMID,却无足够的权限执行
bits/ipc.h
中有关 IPC_X 的宏定义
/* Control commands for `msgctl', `semctl', and `shmctl'. */
#define IPC_RMID 0 /* Remove identifier. */
#define IPC_SET 1 /* Set `ipc_perm' options. */
#define IPC_STAT 2 /* Get `ipc_perm' options. */
#ifdef __USE_GNU
# define IPC_INFO 3 /* See ipcs. */
#endif
bits/shm.h
中有关 shmid_ds 的宏定义
/* Data structure describing a shared memory segment. */
struct shmid_ds
{
struct ipc_perm shm_perm; /* operation permission struct */
size_t shm_segsz; /* size of segment in bytes */
__time_t shm_atime; /* time of last shmat() */
#if __WORDSIZE == 32
unsigned long int __unused1;
#endif
__time_t shm_dtime; /* time of last shmdt() */
#if __WORDSIZE == 32
unsigned long int __unused2;
#endif
__time_t shm_ctime; /* time of last change by shmctl() */
#if __WORDSIZE == 32
unsigned long int __unused3;
#endif
__pid_t shm_cpid; /* pid of creator */
__pid_t shm_lpid; /* pid of last shmop */
shmatt_t shm_nattch; /* number of current attaches */
unsigned long int __unused4;
unsigned long int __unused5;
};
bits/ipc.h
中有关 ipc_perm 结构体的宏定义
/* Data structure used to pass permission information to IPC operations. */
struct ipc_perm
{
__key_t __key; /* Key. */
__uid_t uid; /* Owner's user ID. */
__gid_t gid; /* Owner's group ID. */
__uid_t cuid; /* Creator's user ID. */
__gid_t cgid; /* Creator's group ID. */
unsigned short int mode; /* Read/write permission. */
unsigned short int __pad1;
unsigned short int __seq; /* Sequence number. */
unsigned short int __pad2;
unsigned long int __unused1;
unsigned long int __unused2;
};
以下函数可以进行信号量和共享内存的创建与控制
通过各方面资料弄懂其参数的意义和返回值的类型,是熟练掌握的基础
原文地址
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。