操作系统编程作业速查手册
只是一些和作业有关的速记
引流:使用linux系统提供的系统调用msgget(),msgrev(),msgctl()编制一个长度为1K的消息发送和接受的程序
fork
fork一个新进程
在父进程中,fork()返回新创建子进程的进程ID
在子进程中,fork()返回0
message queue
POSIX.1‐2017 defination: 3.226 Message Queue 3.226 消息队列 In the context of programmatic message passing, an object to which messages can be added and removed. Messages may be removed in the order in which they were added or in priority order.
在编程消息传递的上下文中,可以向其添加和删除消息的对象。邮件可以按添加顺序或优先级顺序删除。
本部分参考资料
总而言之还是建议看英文原版一手资料手册,中文教程和ai回答的很多细节模糊,会导致debug非常难办
msg_queue 里传递的消息格式
在msg_queue里传递的格式有特定的要求:
结构体里的第一个元素是一个数据类型为long的message type
实际接收消息的缓冲区,建议为一个数组或者结构体较为便利,具体细节参考这个回答
msgget
原型:msgget(key_t key,int flag)
参数含义:
key:消息队列的键值。如果该键值对应的消息队列不存在,则根据 flag 参数的值创建一个新的消息队列。
flag:控制函数行为的标志,取值可以是 0 或 IPC_CREAT。 返回值:成功后,msgget() 返回消息队列标识符(非负整数) 注意事项:server端flag=
0777|IPC_CREAT
,0777代表文件权限,含义是表示创建的消息队列的访问权限为所有者、所属组和其他用户都具有读、写和执行权限,IPC_CREAT代表创建队列。而client端flag=0777
,无需重复创建新的队列
msgrcv
原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
参数含义:
msgqid:消息队列的标识符。
msgp:指向接收消息的缓冲区。
msgsz:需要接收消息的大小,注意,不包括mtype
msgtyp:指定要接收的消息类型。
如果为 0,则表示接收队列中的第一条消息。
如果不为0,接受mtype==msgtype的消息
msgflg:控制函数行为的标志,取值可以是 0 或 IPC_NOWAIT。
函数返回值为成功接收到的消息字节数
msgsnd
原型:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数含义:
msgid:消息队列的标识符。
msgp:指向要发送的消息的缓冲区。
msgsz:发送消息的长度
msgflg:控制函数行为的标志,取值可以是 0 或 IPC_NOWAIT。
函数返回值为 0 表示成功,如果出错则返回 -1
命令行工具
ipcs
在命令行里返回全部的消息队列和状态,示例如下:
ipcrm -q <queue_id>
删除某个指定id的消息队列
Linux信号量集
Linux信号量作为IPC机制的一种,与其他通信方式类似,Linux也是通过kern_ipc_perm结构中的key来唯一标志一个信号量集,并通过该结构设置并检查访问权限。针对信号量集,系统维护一个由信号量集组成的数组,数组中的每个单元指向一个信号量集。
创建新的信号量集或获取已存在的信号量集
`int semget(key_t key ,int nsems ,int flag)`
参数说明:
key:用户指定一个非0整数型值,对信号量集的打开或存取依赖于semflg参数的取值。
nsems:指定打开或者新创建的信号量集将包含的信号量的数目。
flag:
若只设置semflg的IPC_CREAT位,则创建一个信号量集,如果该信号量集已经存在,则返回其标识符。
semflg的IPC_CREAT|IPC_EXCL位,则创建一个新的信号量集,如果该key值的信号量已经存在,则返回错误信息。
只设置IPC_EXCL而不设置IPC_CREAT位没有任何意义
返回值:正确返回信号量集的标识符,错误时返回-1。
例如,创建一个只包含一个信号量的信号量集:
对信号量的PV操作
`int semop(int semid ,struct sembuf *sops ,unsigned nsops);`
参数说明:
semid:是信号量集的标识符,由semget()得到
sops:指向一个sembuf结构数组,该数组的每一个元素对以一次信号量操作。
struct sembuf解释见下
nsops:进行操作信号量的个数,即sops结构变量的个数,需大于或等于1。最常见设置此值等于1,只完成对一个信号量的操作
sem_num标明它是信号量集的第几个元素,从0开始
sem_op指定信号量采取的操作
<0
相当于P操作,占有资源>0
相当于V操作,释放资源=0
进程睡眠直到信号量的值为0
sem_flg指明操作的执行模式,两个标志位。一个是IPC_NOWAIT,指明以非阻塞方式操作信号量。一个是SEM_UNDO,指明内核为信号量操作保留恢复值。
当操作信号量(semop)时,sem_flg可以设置SEM_UNDO标识;SEM_UNDO用于将修改的信号量值在进程正常退出(调用exit退出或main执行完)或异常退出(如段异常、除0异常、收到KILL信号等)时归还给信号量。
如信号量初始值是20,进程以SEM_UNDO方式操作信号量减2,减5,加1;在进程未退出时,信号量变成20-2-5+1=14;在进程退出时,将修改的值归还给信号量,信号量变成14+2+5-1=20。
返回值:正确返回0,错误时返回-1
信号量集的控制函数
int semctl(int semid ,int semnum ,int cmd ,union semun arg);
参数说明:
semid:是信号量集的标识符,由semget()得到
semnum:指定semid信号量集的第几个信号量,在撤销信号量集时,此参数可缺省。
cmd:指定操作类型。
arg:数据类型是共同体类型semun,该类型在include/linux/sem.h中定义
取值 含义
GETVAL 返回semnum指定的信号量的semval域值
SETVAL 指定semval域值为arg.val
GETPID 返回semnum指定信号量sempid
GETNCNT 返回semncnt
GETZCNT 返回semzcnt
GETALL 返回所有信号量的值,结果保存到arg.array中
SETALL 通过arg.array更新所有信号量的值
IPC_STAT 获取信号量集的arg.array,存入arg.buf
IPC_SET 将arg.buf数据结构的sem_perm.uid,sem_perm.gid,sem_perm.mode赋给sem_array,此操作仅限root、sem_perm.cuid或sem_perm.uid
IPC_RMID 删除指定信号量集。此操作仅限root、sem_perm.cuid或sem_perm.uid
IPC_INFO 获取信号量集的相关信息存放于arg.buf中
返回值:正确时根据cmd的的不同返回值或0,错误时返回-1。
例如:撤销信号量集 semctl(semid ,IPC_RMID ,0)
共享内存
shmget
原型和头文件:
参数分别是:
进程间通信键值
共享内存大小
权限等级
shmat
shmat
函数是 Linux 系统编程中用于将共享内存连接到当前进程的地址空间中的函数
该函数的参数包括共享内存标识符、连接地址和标志等。调用该函数会返回一个指向共享内存第一个字节的指针。
共享内存标识符:由
shmget
函数返回的共享内存标识符。连接地址:指定共享内存连接到当前进程的地址,通常设置为
NULL
。标志:指定连接方式,包括只读和读写等。
shmdt
shmdt
函数是 Linux 系统编程中用于将共享内存从当前进程的地址空间中分离的函数之一。它的原型如下:
该函数的参数是由 shmat
函数返回的地址指针。调用该函数会将共享内存从当前进程的地址空间中分离,但并不会删除共享内存。调用成功时返回 0
,失败时返回 -1
。
shmctl
shmctl
函数是 Linux 系统编程中用于控制共享内存的函数之一。它的原型如下:
该函数的参数包括共享内存标识符、命令和 shmid_ds
结构体等。调用该函数可以对共享内存进行多种操作,包括获取共享内存信息、设置共享内存信息、删除共享内存等。
shmid
:由shmget
函数返回的共享内存标识符。cmd
:指定需要执行的操作,包括获取共享内存信息、设置共享内存信息、删除共享内存等。shmid_ds
结构体:用于传递共享内存信息,包括共享内存的大小、访问权限、最后一次连接时间等。
Last updated