IPC_PRIVATE
IPC_PRIVATE
是用于创建新的 System V IPC(Inter-Process Communication,进程间通信)对象的特殊键值。在使用 System V 共享内存、消息队列或信号量时,IPC_PRIVATE
可以作为 key
参数传递给 shmget
、msgget
或 semget
函数,以创建一个新的 IPC 对象, IPC_PRIVATE可以替换为自己的唯一key
特点
- 唯一性 :使用
IPC_PRIVATE
创建的 IPC 对象是唯一的,只有创建它的进程及其子进程能够访问。这是因为IPC_PRIVATE
实际上并不是一个真正的键值,而是一个特殊标识符,指示内核为调用进程创建一个新的、唯一的 IPC 对象。 - 进程间隔离 :由于
IPC_PRIVATE
创建的对象不依赖于一个全局可见的键值,其他进程无法通过键值访问该对象,除非它们是通过继承的方式(如 fork)获得的。
IPC_PRIVATE
例子
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>
#include <unistd.h>
#define SHM_SIZE 1024 // 共享内存大小
int main() {
// 创建共享内存段
int shm_id = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666);
if (shm_id == -1) {
perror("shmget");
exit(EXIT_FAILURE);
}
// 附加共享内存段
char *shm_ptr = (char *)shmat(shm_id, NULL, 0);
if (shm_ptr == (char *)-1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 写入数据到共享内存
strncpy(shm_ptr, "Hello, Shared Memory!", SHM_SIZE);
// 创建子进程
pid_t pid = fork();
if (pid == 0) {
// 子进程读取共享内存
printf("Child process reads: %s\n", shm_ptr);
// 分离共享内存段
if (shmdt(shm_ptr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
exit(0);
} else if (pid > 0) {
// 父进程等待子进程结束
wait(NULL);
// 分离共享内存段
if (shmdt(shm_ptr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
// 删除共享内存段
if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(EXIT_FAILURE);
}
} else {
perror("fork");
exit(EXIT_FAILURE);
}
return 0;
}
自定义Key举例
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/shm.h>
#include <errno.h>
#include <stdio.h>
#include <sys/sem.h>
#define DENY_MAC_SHM_SIZE 18 // MAC地址长度为17个字符,加上一个终止符
#define SHM_MAC_INFO_KEY (0x00260000)
char *g_deny_mac = NULL;
int shm_init(unsigned int key,int shm_id)
{
//int shm_id = -1;
void *shm = NULL;
if(NULL != g_deny_mac)
{
printf("share memory had already init\r\n");
return 0;
}
else
{
shm_id = shmget((key_t)SHM_MAC_INFO_KEY,DENY_MAC_SHM_SIZE,IPC_CREAT|0666);
if(shm_id == -1)
{
printf("shmget failed:%s\n",strerror(errno));
return -1;
}
shm = shmat(shm_id,NULL,0);
g_deny_mac = (char *)shm;
}
return 0;
}
int set_deny_mac(char *mac,int len)
{
int ret = 0;
void *deny_mac = NULL;
deny_mac = g_deny_mac;
if(mac != NULL)
{
memcpy(deny_mac,mac,len);
}
else
{
ret = -1;
}
return ret;
}
int get_deny_mac(char *mac, int len)
{
int ret = -1;
void *deny_mac = NULL;
deny_mac = g_deny_mac;
memcpy(mac,g_deny_mac,len);
if(strlen(mac) == len)
{
ret = 0;
}
else
{
ret = -1;
}
return ret;
}
void shm_free(int shm_id)
{
void *shm_ptr = shmat(shm_id, NULL, 0);
if (shm_ptr == (void *)-1) {
perror("shmat");
exit(EXIT_FAILURE);
}
// 分离共享内存段
if (shmdt(shm_ptr) == -1) {
perror("shmdt");
exit(EXIT_FAILURE);
}
// 删除共享内存段
if (shmctl(shm_id, IPC_RMID, NULL) == -1) {
perror("shmctl");
exit(EXIT_FAILURE);
}
return ;
}
int main()
{
char mac[] = "xx:xx:xx:00:00:01";
char buf[18] = {0};
int shm_id;
shm_init(SHM_MAC_INFO_KEY,shm_id);
get_deny_mac(buf,sizeof(buf));
printf("buf=%s mac=%s\n",buf,mac);
set_deny_mac(mac,18);
get_deny_mac(buf,18);
printf("buf=%s mac=%s\n",buf,mac);
shm_free(shm_id);
return 0;
}