进程间通信
ftok
k的使用
1,如果两个参数相同,那么产生的 key 值也相同。
2,第一个参数一般取进程所在的目录,因为在一个项目中需要通信的几个进程通常会
出现在同一个目录当中。
3,如果同一个目录中的进程需要超过 1 个 IPC 对象,可以通过第二个参数来标识。
4,系统中只有一套 key 标识,也就是说,不同类型的 IPC 对象也不能重复。
进程间通信
c
#include "head.h"
int main(int argc,char *argv[])
{
// 1、获取键值
// (1) 如果两个参数相同,那么产生的key值也相同。
// (2) 第一个参数一般取进程所在的目录,因为在一个项目中需要通信的几个进程通常会
// 出现在同一个目录当中。
// (3) 如果同一个目录中的进程需要超过1个IPC对象,可以通过第二个参数来标识。
// (4) 系统中只有一套key标识,也就是说,不同类型的IPC对象也不能重复。
key_t key = ftok(".", 1);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
// NULL 代表系统自动寻找合适内存进行映射
// 0 代表映射的这块区域我可读可写
char* ptr = shmat(shmid, NULL, 0);
// 4、给共享内存写入数据
char buf[] = "0123456789";
// 下面这段代码只使用了共享内存中的一个字节
// 注意目的是为了验证共享内存在没有信号量等机制保证时,内存数据会出现践踏。
int i = 0;
while(1)
{
*ptr = buf[i++];
if (i == 10)
{
i = 0;
}
}
return 0;
}
#include "head.h"
int main(int argc,char *argv[])
{
// 1、获取键值
// (1) 如果两个参数相同,那么产生的key值也相同。
// (2) 第一个参数一般取进程所在的目录,因为在一个项目中需要通信的几个进程通常会
// 出现在同一个目录当中。
// (3) 如果同一个目录中的进程需要超过1个IPC对象,可以通过第二个参数来标识。
// (4) 系统中只有一套key标识,也就是说,不同类型的IPC对象也不能重复。
key_t key = ftok(".", 1);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
// NULL 代表系统自动寻找合适内存进行映射
// 0 代表映射的这块区域我可读可写
char* ptr = shmat(shmid, NULL, 0);
// 4、给共享内存写入数据
while(1)
{
printf("%c", *ptr);
}
return 0;
}
c
#include "head.h"
struct msgbuf
{
long mtype;
char str1[255];
char str2[255];
};
int main(int argc,char *argv[])
{
// 1、获取key值,当前key在整个IPC中是通用的
key_t key = ftok(".", 2);
// 2、获取消息队列的ID
int msgid = msgget(key, IPC_CREAT | 0644);
// 3、组装消息,然后发送
struct msgbuf buf;
buf.mtype = 1L;
bzero(buf.str1, sizeof(buf.str1));
bzero(buf.str2, sizeof(buf.str2));
fgets(buf.str1, sizeof(buf.str1), stdin);
fgets(buf.str2, sizeof(buf.str2), stdin);
msgsnd(msgid, &buf, sizeof(buf), 0); // 0 表示阻塞等待
return 0;
}
c
#include "head.h"
struct msgbuf
{
long mtype;
char str1[255];
char str2[255];
};
int main(int argc,char *argv[])
{
// 1、获取key值,当前key在整个IPC中是通用的
key_t key = ftok(".", 2);
// 2、获取消息队列的ID
int msgid = msgget(key, IPC_CREAT | 0644);
// 3、初始化结构体,然后接收数据
struct msgbuf buf;
bzero(buf.str1, sizeof(buf.str1));
bzero(buf.str2, sizeof(buf.str2));
msgrcv(msgid, &buf, sizeof(buf), 1L, 0); // 0 表示阻塞等待
puts(buf.str1);
puts(buf.str2);
return 0;
}
#include "head.h"
#define DATA 0 // 用于表示信号量元素的下标
#define SPACE 1
/* 函数功能:初始化一个信号量元素
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
* 参数3: 在这块我们使用SETVAL,表示给信号量元素设置初值
* 参数4: 给信号量元素设置的具体值
*/
void init_sem(int id, int num, int val)
{
semctl(id, num, SETVAL, val);
}
/* 函数功能:通过信号量元素的设备,执行P操作
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
*/
void sem_p(int id, int num)
{
struct sembuf buf[1];
buf[0].sem_num = num; // 信号量元素的下标
buf[0].sem_op = -1; // 执行P操作
buf[0].sem_flg = 0; // 通常不使用
// 执行P操作
semop(id, buf, 1); // 1 代表数组中元素的个数
}
/* 函数功能:通过信号量元素的设备,执行V操作
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
*/
void sem_v(int id, int num)
{
struct sembuf buf[1];
buf[0].sem_num = num; // 信号量元素的下标
buf[0].sem_op = 1; // 执行V操作
buf[0].sem_flg = 0; // 通常不使用
// 执行V操作
semop(id, buf, 1); // 1 代表数组中元素的个数
}
int main(int argc,char *argv[])
{
/************************* 共享内存操作 **********************/
// 1、获取键值,提供给共享内存使用
key_t key = ftok(".", 3);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
char* ptr = shmat(shmid, NULL, 0);
/************************* 信号量操作 **********************/
// 4、获取键值,提供给信号量使用
key_t sem_key = ftok(".", 4);
// 5、获取信号量的ID
// 第二个参数用于表示信号量元素的个数
int semid = semget(key, 2, IPC_CREAT | 0644);
// 6、初始化两个信号量元素
init_sem(semid, DATA, 0); // 初始化无数据
init_sem(semid, SPACE, 1); // 初始化有资源
// 7、给共享内存写入数据
char buf[] = "0123456789";
// 下面这段代码只使用了共享内存中的一个字节
// 注意目的是为了验证共享内存在没有信号量等机制保证时,内存数据会出现践踏。
int i = 0;
while(1)
{
// 8、执行P操作,申请资源,增加数据
sem_p(semid, SPACE);
*ptr = buf[i++];
if (i == 10)
{
i = 0;
}
// 9、资源减少,数据增加
sem_v(semid, DATA);
}
return 0;
}
c
#include "head.h"
#define DATA 0 // 用于表示信号量元素的下标
#define SPACE 1
/* 函数功能:初始化一个信号量元素
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
* 参数3: 在这块我们使用SETVAL,表示给信号量元素设置初值
* 参数4: 给信号量元素设置的具体值
*/
void init_sem(int id, int num, int val)
{
semctl(id, num, SETVAL, val);
}
/* 函数功能:通过信号量元素的设备,执行P操作
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
*/
void sem_p(int id, int num)
{
struct sembuf buf[1];
buf[0].sem_num = num; // 信号量元素的下标
buf[0].sem_op = -1; // 执行P操作
buf[0].sem_flg = 0; // 通常不使用
// 执行P操作
semop(id, buf, 1); // 1 代表数组中元素的个数
}
/* 函数功能:通过信号量元素的设备,执行V操作
* 参数1: 信号量的ID
* 参数2: 当前信号量元素的下标
*/
void sem_v(int id, int num)
{
struct sembuf buf[1];
buf[0].sem_num = num; // 信号量元素的下标
buf[0].sem_op = 1; // 执行V操作
buf[0].sem_flg = 0; // 通常不使用
// 执行V操作
semop(id, buf, 1); // 1 代表数组中元素的个数
}
int main(int argc,char *argv[])
{
/************************* 共享内存操作 **********************/
// 1、获取键值,提供给共享内存使用
key_t key = ftok(".", 3);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
char* ptr = shmat(shmid, NULL, 0);
/************************* 信号量操作 **********************/
// 4、获取键值,提供给信号量使用
key_t sem_key = ftok(".", 4);
// 5、获取信号量的ID
// 第二个参数用于表示信号量元素的个数
int semid = semget(key, 2, IPC_CREAT | 0644);
// 6、初始化两个信号量元素
init_sem(semid, DATA, 0); // 初始化无数据
init_sem(semid, SPACE, 1); // 初始化有资源
// 下面这段代码只使用了共享内存中的一个字节
while(1)
{
// 7、执行P操作,申请数据(想要进行读操作),数据减少
sem_p(semid, DATA);
printf("%c", *ptr);
// 9、资源增加,数据减少
sem_v(semid, SPACE);
}
return 0;
}
#include "head.h"
int main(int argc,char *argv[])
{
/************************* 共享内存操作 **********************/
// 1、获取键值,提供给共享内存使用
key_t key = ftok(".", 3);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
char* ptr = shmat(shmid, NULL, 0);
/************************* 信号量操作 **********************/
// 4、创建POSIX信号 /space
sem_t* space = sem_open("/space", O_EXCL);
if (space == SEM_FAILED)
{
space = sem_open("/space", O_CREAT, 0644, 1);
}
// 4、创建POSIX信号 /data
sem_t* data = sem_open("/data", O_EXCL);
if (data == SEM_FAILED)
{
data = sem_open("/data", O_CREAT, 0644, 0);
}
// 5、给共享内存写入数据
char buf[] = "0123456789";
// 下面这段代码只使用了共享内存中的一个字节
// 注意目的是为了验证共享内存在没有信号量等机制保证时,内存数据会出现践踏。
int i = 0;
while(1)
{
// 6、申请资源,无资源时阻塞等待
sem_wait(space); // while(SPACE == 0);
// 7、向共享内存中写入数据
*ptr = buf[i++];
if (i == 10)
{
i = 0;
}
// 8、投递数据
sem_post(data);
}
return 0;
}
c
#include "head.h"
int main(int argc,char *argv[])
{
/************************* 共享内存操作 **********************/
// 1、获取键值,提供给共享内存使用
key_t key = ftok(".", 3);
// 2、获取共享内存ID
int shmid = shmget(key, 1024, IPC_CREAT | 0644);
// 3、实现内存映射
char* ptr = shmat(shmid, NULL, 0);
/************************* 信号量操作 **********************/
// 4、创建POSIX信号 /space
sem_t* space = sem_open("/space", O_EXCL);
if (space == SEM_FAILED)
{
space = sem_open("/space", O_CREAT, 0644, 1);
}
// 4、创建POSIX信号 /data
sem_t* data = sem_open("/data", O_EXCL);
if (data == SEM_FAILED)
{
data = sem_open("/data", O_CREAT, 0644, 0);
}
while(1)
{
// 5、申请数据,无数据时阻塞等待
sem_wait(data); // while(DATA == 0);
// 6、从共享内存中读取数据
printf("%c", *ptr);
// 7、投递资源
sem_post(space);
}
return 0;
}