1. ftok 函数
描述
利用路径名与标识符生成一个供 System V IPC 使用的 key 值
概要
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
返回值
成功返回 key_t 的值,失败返回 -1
操作示例
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
int main()
{
char filename[50];
struct stat buf;
int ret;
strcpy(filename, "/tmp/shm");
ret = stat(filename, &buf);
if (ret == -1)
{
perror("stat error");
return -1;
}
fprintf(stdout, "ftok(filename, 1024)= %x, st_ino= %x, st_dev=%x\n", ftok(filename, 1024), buf.st_ino, buf.st_dev);
// 输出:ftok(filename, 1024)= 12996, st_ino= 4032996, st_dev=fd01
// 本质上 ftok 应该输出值为 0x00012996 , 即1024后两位,st_dev后两位,st_ino后两位
}
2. semctl 函数
描述
System V 信号量控制和操作函数
概要
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semctl(int semid, int semnum, int cmd, ...);
This function has three or four arguments, depending on cmd. When there are four, the fourth has the type union semun. The calling program must define this union as follows:
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) */
};
返回值
失败时, semctl() 返回 -1 ;成功当cmd = SETALL 时返回 0
3. semop 函数
描述
semop, semtimedop - System V semaphore operations
概要
// 按 sops 结构指定的方式处理semid指向的信号量集中的 nsops 个信号量
int semop(int semid, struct sembuf *sops, size_t nsops);
struct sembuf {
unsigned short sem_num; /* semaphore number, the first semaphore of
the set is numbered 0 */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
};
// sem_op 为正数时是 V 操作,即释放资源
// sem_op 为负数时是 P 操作,即获取资源
// sem_flg = IPC_NOWAIT or SEM_UNDO
返回值
If successful, semop() return 0; otherwise they return -1 with errno indicating the error.
4. shmat 与 shmdt
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);
返回值
On success, shmat() returns the address of the attached shared memory segment; on error, (void *) -1 is returned, and errno is set to indicate the cause of the error.
On success, shmdt() returns 0; on error -1 is returned, and errno is set to indicate the cause of the error.
5. 示例代码
具体使用方法,详见附件 shared_memory_demo.zip , 以下仅是对shm系统调用的封装:
#define MAX_NUM 128
// 共享内存消息结构体
struct shm_data {
int data[MAX_NUM];
int datalength;
};
// 用于初始化信号量结构体
union semun {
int val;
struct semid_ds *buf;
unsigned short int *array;
struct seminfo *__buf;
};
// 创建共享内存 id
int get_shmid() {
int shmid;
key_t key;
if ((key = ftok("/tmp/shm/", 1024)) < 0) {
perror("ftok error");
return -1;
}
shmid = shmget(key, sizeof(struct shm_data), IPC_CREAT|0777);
return shmid;
}
// 创建信号量 id
int get_semaphoreid() {
int semid;
key_t key;
if ((key = ftok("/tmp/sem/", 1024)) < 0) {
perror("ftok error");
return -1;
}
semid = semget(key, 1, IPC_CREAT|0777);
return semid;
}
// 初始化信号量
int semaphore_init(int semid) {
union semun argument;
unsigned short int values[1];
values[0] = 1;
argument.array = values;
return semctl(semid, 0, SETALL, argument);
}
// 对信号量进行 p 操作
int semaphore_p(int semid) {
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = -1;
operations[0].sem_flg = SEM_UNDO;
return semop(semid, operations, 1);
}
// 对信号量进行 v 操作
int semaphore_v(int semid) {
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = 1;
operations[0].sem_flg = SEM_UNDO;
return semop(semid, operations, 1);
}