key_t key = ftok("/home", 123);
if (key > 0)
{
perror("获取成功");
}
else
{
perror("获取失败");
}
注意:
此时消息队列已经在内核中创建完成了,接下来就可以发送消息了。同时也可以用命令查看消息队列的相关属性:
进程通信.c
#include "进程通信.h"
// 线程1发送消息
void *send_msg(void *arg)
{
int op;
while (1)
{
op = 2;
memset(&buf, 0, sizeof(buf));
printf("请选择操作\n");
printf("1.发送信息\n");
printf("2.退出\n");
scanf("%d", &op);
// while (getchar() != '\n')
// ;
if (op == 1)
{
// printf("op1=%d\n", op);
printf("请输入接收者的pid,和消息内容\n");
scanf("%ld", &buf.mtype);
// while (getchar() != '\n')
// ;
scanf("%s", buf.data);
// while (getchar() != '\n')
// ;
int res = msgsnd(resource.msgque_id, &buf, strlen(buf.data), 0);
if (res == 0)
{
perror(" msgsnd ok");
}
continue;
}
if (op == 2)
{
// printf("op2=%d\n", op);
printf("break\n");
break;
}
// printf("op3=%d\n", op);
}
}
// 线程2接受消息
void *rcv_msg(void *arg)
{
memset(&buf, 0, sizeof(buf));
buf.mtype = resource.my_info.pid;
while (1)
{
memset(buf.data, 0, sizeof(buf.data));
int res = msgrcv(resource.msgque_id, &buf, sizeof(buf.data), buf.mtype, 0);
printf("收到消息:%s\n", buf.data);
}
}
// 资源准备,打开文件目录,消息队列以及,共享内存等
int Prepare_for()
{
// 创建消息队列----------------
// 消息队列创建key
key_t msgque_key = ftok("/home", 123);
if (msgque_key < 0)
{
perror("msgque_key fail");
}
else
{
perror("msgque_key");
}
// 获取消息队列msgid
resource.msgque_id = msgget(msgque_key, IPC_CREAT | 0777);
if (resource.msgque_id < 0)
{
perror("resource.msgque_id fail");
}
else
{
perror("resource.msgque_id");
}
// 创建共享内存---------------
// 获取共享内存key
key_t shmsg_key = ftok("/home", 123);
if (shmsg_key < 0)
{
perror("shmsg_key");
}
else
{
perror("shmsg_key");
}
// 获取共享内存shm_id
resource.shm_id = shmget(shmsg_key, sizeof(Shared_memory) * 100, IPC_CREAT | 0777);
if (resource.shm_id < 0)
{
perror("resource.shm_id");
}
else
{
perror("resource.shm_id");
}
// 映射共享内存
resource.shm_map_poi = (Shared_memory *)shmat(resource.shm_id, NULL, 0);
if (resource.shm_map_poi == (Shared_memory *)-1)
{
perror("resource.shm_map_poi");
}
else
{
perror("resource.shm_map_poi");
}
resource.flag = 1;
return 0;
}
// 退出资源摧毁
int Destroy()
{
// printf("22\n");
// 下线删除数据
delete_info();
// printf("22\n");
// printf("11\n");
// 回收线程
pthread_cancel(resource.read_id);
// pthread_cancel(resource.write_id);
// printf("11\n");
// pthread_join(resource.write_id, NULL);
pthread_join(resource.read_id, NULL);
// 下线通知
signal(12, SIG_IGN);
system("killall -12 test");
// 摧毁消息队列
struct shmid_ds ipc_info;
shmctl(resource.shm_id, IPC_STAT, &ipc_info);
if (ipc_info.shm_nattch == 1)
{
shmctl(resource.shm_id, IPC_RMID, NULL);
msgctl(resource.msgque_id, IPC_RMID, NULL);
}
}
int main(int argc, char const *argv[])
{
// 资源准备,打开文件目录,消息队列以及,共享内存等
Prepare_for();
// 录入自己的信息
resource.my_info.pid = getpid();
printf("我的pid=%d\n", resource.my_info.pid);
strcpy(resource.my_info.name, argv[1]);
node_info();
printf_friends();
// 上线通知信号10
signal(10, sig_up);
// 下线通知信号12
signal(12, sig_down);
signal(10, SIG_IGN);
system("killall -10 test");
signal(10, sig_up);
// 线程2收消息----------------------------------------------
pthread_create(&resource.read_id, NULL, rcv_msg, NULL);
// 主线程发送消息--------------------------------------------
// pthread_create(&resource.write_id, NULL, send_msg, NULL);
send_msg(NULL);
// rcv_msg(NULL);
// 退出资源摧毁
Destroy();
return 0;
}
进程通信.h
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
// 共享内存结构体
typedef struct Shared_memory
{
pid_t pid;
char name[32];
} Shared_memory;
struct msgbuf
{
long mtype;
char data[100];
} buf;
typedef struct Resources
{
int msgque_id;
int shm_id;
Shared_memory *shm_map_poi;
int flag;
pthread_t read_id;
pthread_t write_id;
Shared_memory my_info;
} Resources;
// 各类资源准备结构体
Resources resource;
// 主体函数--------------------------------------------------------
// 资源准备,打开文件目录,消息队列以及,共享内存等
int Prepare_for();
// 线程1发送消息
void *send_msg(void *arg);
// 线程2接受消息
void *rcv_msg(void *arg);
// 退出资源摧毁
int Destroy();
// 功能函数-----------------------------------------------------------
// 上线告知所有进行
void sig_up(int sig);
// 下线通知所有进程
void sig_down(int sig);
// 读取在线好友
int printf_friends();
// 上线录入数据
int node_info();
// 下线删除数据
int delete_info();
进程通信功能函数.c
#include "进程通信.h"
// 上线告知所有进行
void sig_up(int sig)
{
printf("你的好友已上线\n");
printf_friends();
}
// 下线通知所有进程
void sig_down(int sig)
{
printf("你的好友已下线\n");
printf_friends();
}
// 读取在线好友
int printf_friends()
{
Shared_memory *temp_friend = resource.shm_map_poi;
int i = 1;
printf("您的在线好友:\n");
while (1)
{
i++;
if (i == 100)
{
break;
}
if (temp_friend->pid == 0)
{
continue;
}
else
{
if (strcmp(temp_friend->name, resource.my_info.name) != 0)
{
printf("pid=%d %s(在线)\n", temp_friend->pid, temp_friend->name);
}
}
// printf("%d\n", i);
temp_friend++;
}
}
// 上线录入数据
int node_info()
{
int i = 1;
Shared_memory *temp_friend = resource.shm_map_poi;
while (1)
{
if (temp_friend->pid == 0)
{
*temp_friend = resource.my_info;
break;
}
temp_friend++;
i++;
if (i == 100)
{
break;
}
}
}
// 下线删除数据
int delete_info()
{
int i = 1;
Shared_memory *temp_friend = resource.shm_map_poi;
while (1)
{
if (strcmp(temp_friend->name, resource.my_info.name) == 0)
{
memset(temp_friend, 0, sizeof(Shared_memory));
break;
}
temp_friend++;
i++;
if (i == 100)
{
break;
}
}
}
---------------------------------------------------------------------------------------------------------------------------------
这还一个写的比较乱的。
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct people
{
pid_t pid;
char name[32];
int flag;
int flag2;
} friend;
struct msgbuf
{
long mtype;//这个必须有消息队列就是根据type值区分不同消息的
char bata[100];//大小随便改
} buf;//消息队列指定结构体。
int msg_id;
struct people *friend_list;
int printf_friends();
struct people *add_friend_list();
struct people *add_friend_list()
{
struct people *temp_friend = friend_list;
int i = 0;
while (1)
{
if (temp_friend->pid == 0)
{
*temp_friend = friend;
return temp_friend;
}
else
{
if (strcmp(temp_friend->name, friend.name) == 0)
{
*temp_friend = friend;
return temp_friend;
}
}
temp_friend++;
}
return (struct people *)-1;
}
void Signal_registration(int sig);
void Signal_registration(int sig)
{
struct people *temp_friend = friend_list;
int i = 0;
while (1)
{
if (temp_friend->pid == 0)
{
return;
}
else
{
if (temp_friend->flag2 == 0 && strcmp(temp_friend->name, friend.name) != 0)
{
printf("您的好友:%s已上线\n", temp_friend->name);
printf_friends();
return;
}
}
temp_friend++;
}
}
void Signal_registration_down(int sig);
void Signal_registration_down(int sig)
{
struct people *temp_friend = friend_list;
// int i = 0;
while (1)
{
if (temp_friend->pid == 0)
{
return;
}
else
{
if (temp_friend->flag2 == 0 && strcmp(temp_friend->name, friend.name) != 0)
{
printf("您的好友:%s已下线\n", temp_friend->name);
temp_friend->flag = 0;
printf_friends();
return;
}
}
temp_friend++;
}
}
int printf_friends()
{
struct people *temp_friend = friend_list;
int i = 0;
printf("您的在线好友:\n");
while (1)
{
if (temp_friend->pid == 0)
{
return 0;
}
else
{
if (temp_friend->flag == 1 && strcmp(temp_friend->name, friend.name) != 0)
{
printf("%d.%s在线\n", i + 1, temp_friend->name);
}
}
temp_friend++;
}
}
void send_mas_name(char *name);
void send_mas_name(char *name)
{
if (friend_list->pid == 0)
{
printf("您没有好友,发送失败");
return ;
}
struct people *temp_friend = friend_list;
while (1)
{
if (strcmp(temp_friend->name, name) == 0)
{
char rcvfriend[100];
key_t key = ftok("/home", 123);
if (key > 0)
{
// perror("获取成功");
}
else
{
perror("获取失败");
}
msg_id = msgget(key, IPC_CREAT | 0777);
if (msg_id < 0)
{
perror("消息队列创建失败");
}
printf("请输入您要发送的消息:");
scanf("%s", buf.bata);
buf.mtype=temp_friend->pid;
int res = msgsnd(msg_id, &buf, strlen(buf.bata), IPC_NOWAIT);
if (res == 0)
{
// perror(" msgsnd ok");
}
sprintf(rcvfriend, "kill -14 %d ", temp_friend->pid);
system(rcvfriend);
return ;
}
temp_friend++;
}
}
void fun(struct people *my_info);
void fun(struct people *my_info)
{
int operat_exti;
while (1)
{
printf_friends();
printf("是否需要退出\n");
printf("1、退出\n");
printf("2、发送消息\n");
scanf("%d", &operat_exti);
if (operat_exti == 1)
{
my_info->flag = friend.flag = 0;
my_info->flag2 = 0;
system("killall -10 test");
my_info->flag2 = 1;
break;
}
if (operat_exti == 2)
{
char msg[1024];
char name[32];
printf("发送给谁:\n");
scanf("%s", name);
send_mas_name(name);
}
// printf_friends();
}
}
void rcv_fun(int sig)
{
key_t key = ftok("/home", 123);
if (key > 0)
{
// perror("获取成功");
}
else
{
perror("获取失败");
}
msg_id = msgget(key, IPC_CREAT | 0777);
if (msg_id < 0)
{
perror("消息队列创建失败");
}
memset(buf.bata,0,sizeof(buf));
buf.mtype=getpid();
int res=msgrcv(msg_id,&buf,sizeof(buf.bata),buf.mtype,0);
printf("收到消息:%s\n",buf.bata);
getchar();
}
int main(int argc, char const *argv[])
{
friend.pid = getpid();
printf("friend.pid =%d\n",friend.pid);
strcpy(friend.name, argv[1]);
friend.flag = 1; // 上线
friend.flag2 = 1; // 正常
//------------------共享空间写入---------------------------
key_t key = ftok("/home", 321);
if (key == -1)
{
perror("key");
}
else
{
// printf("key success\n");
}
int shmid = shmget(key, 4096, IPC_CREAT | 0777);
if (shmid == -1)
{
perror("shmget");
}
else
{
// printf("shmget success\n");
}
friend_list = (struct people *)shmat(shmid, NULL, 0);
struct people *my_info = add_friend_list();
if (my_info == (struct people *)-1)
{
perror("add_friend_list fail");
}
else
{
// printf("add_friend_list success\n");
}
//-----------------上线通知------------------------------------
signal(12, Signal_registration);
my_info->flag2 = 0;
system("killall -12 test");
my_info->flag2 = 1;
//-----------------读取消息---------------------------------
signal(14, rcv_fun);
//----------------下线通知----------------------------------
signal(10, Signal_registration_down);
fun(my_info);
//
//----------------------退出判断是否销毁共享内存------------------
struct shmid_ds ipc_info;
shmctl(shmid, IPC_STAT, &ipc_info);
if (ipc_info.shm_nattch == 1)
{
shmctl(shmid, IPC_RMID, NULL);
msgctl(msg_id,IPC_RMID,NULL);
}
return 0;
}