1.#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sem.h>
#include <semaphore.h>
union semun
{
int val; /* 当 cmd 为 SETVAL 时使用 */
struct semid_ds *buf; /* 当 cmd 为 IPC_STAT 或 IPC_SET 时使用 */
unsigned short *array; /* 当 cmd 为 GETALL 或 SETALL 时使用 */
struct seminfo *__buf; /* 当 cmd 为 IPC_INFO 时使用 */
};
// 用于 System V 信号量的初始化函数
void sem_init_sysv(int id, int num, int val)
{
union semun a;
a.val = val;
semctl(id, num, SETVAL, a);
}
int main()
{
key_t key = ftok("./", 2);
// 创建共享内存的 IPC 对象
int shmid = shmget(key, 2, IPC_CREAT | 0666); // 共享内存的大小为 2 字节
// 创建 POSIX 信号量并初始化
sem_t *space = sem_open("/my_space", O_CREAT, 0666, 1);
sem_t *data = sem_open("/my_data", O_CREAT, 0666, 0);
char *p = shmat(shmid, NULL, 0); // 映射
char *msg = "0123456789";
int i = 0;
while (1)
{
// 把空间信号量 -1
sem_wait(space);
memcpy(p, msg + i, 1); // 只复制一个字符
// 把数据信号量 +1
sem_post(data);
i = (i + 1) % 10; // (0+1)%10
}
// 如果使用 System V 信号量,则需要以下代码:
// int semid = semget(key, 2, IPC_CREAT | 0666);
// sem_init_sysv(semid, 0, 1); // 对空间信号量初始化
// sem_init_sysv(semid, 1, 0); // 对数据信号量初始化
shmdt(p); // 解除映射
// 关闭和销毁 POSIX 信号量
sem_close(space);
sem_close(data);
sem_unlink("/my_space");
sem_unlink("/my_data");
return 0;
}
2.
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <semaphore.h>
int main()
{
//创建key值和获取共享内存的ID
key_t key = ftok("./",2);
int shm_id = shmget(key,2, IPC_CREAT | 0666);//共享内存的大小,必须是偶数
//将这个共享内存映射至本进程的虚拟空间
char *p = shmat(shm_id, NULL,0);//p就是共享内存的首地址
//打开有名信号量
int sem_close(sem_t *sem);
sem_t *space = sem_open("/my_spsce", O_CREAT);
sem_t *data= sem_open("/my_data", O_CREAT);
while(1)
{
//把数据-1
sem_wait(data);
fprintf(stderr,p);
//把空间+1
sem_post(space);
// 关闭和销毁 POSIX 信号量
sem_close(space);
sem_close(data);
sem_unlink("/my_space");
sem_unlink("/my_data");
return 0;
}