ipc是进程间通信机制,由共享内存,信号量和消息队列组成,三种方法有相同的特点。
标识符:每个ipc结构都又一个唯一的引用标识符,但是标识符是在不同的ipc结构不同,在一个结构内,消息队列,信号量,共享内存之间标识符可能一样。
关键字:通过不同的ipc创建方法(msgget,semget,shmget)会制定一个关键字,key_t(长整型)由内核转变标识符。ftok可以将一个路径和项目id转换为关键字。
创建消息队列
//
// main.cpp
// IPC
//
// Created by 蓝猫 on 2018/11/19.
// Copyright © 2018年 蓝猫. All rights reserved.
//
#include <stdio.h>
#include <iostream>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
using namespace std;
int main(int argc, const char * argv[])
{
int qid;
key_t key;
key=ftok(*(argv), 'a');
if(key<0)
{
cout<<"获取队列键值失败"<<endl;
exit(0);
}
qid=msgget(key,IPC_CREAT|0666);
if(qid<0)
{
cout<<"创建队列失败"<<endl;
exit(0);
}
else
{
cout<<"创建队列成功"<<endl;
}
return 0;
}
建立消息队列进行客户端服务端通信
键值设置为1234
客户端
//
// main.cpp
// Client
//
// Created by 蓝猫 on 2018/11/20.
// Copyright © 2018年 蓝猫. All rights reserved.
//
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <memory>
//#include <error.h>
using namespace std;
typedef struct my_msg
{
long int my_msg_type;//数据类型
char text[BUFSIZ];//消息缓冲区大小
}msgbuf;
class Client
{
private:
int runningflag;//运行标志
int msgid;//消息标志服
public:
Client();//构造方法
void SendMsg();//客户端信息发送
void str_char(string s,char *text);
};
Client::Client()
{
runningflag=1;
msgid=msgget((key_t)1234, IPC_CREAT|0666);//关键字值设置1234 权限666
if(msgid==-1)
{
cout<<"create error"<<endl;
exit(1);
}
else
{
cout<<"create message queue sucess!"<<endl;
}
}
void Client::SendMsg()
{
//msgbuf msg;
while (runningflag)
{
msgbuf msg;
cout<<"请输入想要发送的信息"<<endl;
//string temp;
//cin>>temp;
//str_char(temp, msg.text);
fgets(msg.text, BUFSIZ, stdin);
cout<<msg.text<<endl;
if(msgsnd(msgid, (void*)&msg, BUFSIZ, 0)==-1)
{
perror("send failed\n");
exit(1);
}
else
{
cout<<"send success!"<<endl;
}
if(strncmp(msg.text, "end", 3)==0)
{
runningflag=0;
}
}
}
void Client::str_char(string s,char *text)//字符串和char*的转换
{
text=(char*)s.data();
}
int main(int argc, const char * argv[])
{
cout<<"客户端程序"<<endl;
shared_ptr<Client> cli=make_shared<Client>();
cli->SendMsg();
return 0;
}
服务器端
//
// main.cpp
// Server
//
// Created by 蓝猫 on 2018/11/20.
// Copyright © 2018年 蓝猫. All rights reserved.
//
#include <iostream>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <memory>
//#include <error.h>
using namespace std;
typedef struct my_msg
{
long int my_msg_type;//数据类型
char text[BUFSIZ];//消息缓冲区大小
}msgbuf;
class Server
{
private:
int runningFlg;
int msgid;
long int msg_to_receive;
public:
Server();
void GetMsg();
};
Server::Server():runningFlg(1),msg_to_receive(0)
{
msgid=msgget((key_t)1234, 0666|IPC_CREAT);
if(msgid==-1)
{
cout<<"create error"<<endl;
exit(1);
}
else
{
cout<<"create message queue sucess!"<<endl;
}
}
void Server::GetMsg()
{
while (runningFlg)
{
msgbuf msg;
if(msgrcv(msgid, (void *)&msg, BUFSIZ, msg_to_receive, 0)==-1)
{
perror("receive failed\n");
exit(1);
}
else
{
cout<<"receive success!"<<endl;
}
cout<<"接收的信息是:"<<msg.text<<endl;
if(strncmp(msg.text, "end", 3)==0)
{
runningFlg=0;
}
}
if(msgctl(msgid, IPC_RMID, 0)==-1)
{
perror("删除消息队列失败\n");
exit(1);
}
}
int main(int argc, const char * argv[])
{
cout<<"服务端程序"<<endl;
shared_ptr<Server> cli=make_shared<Server>();
cli->GetMsg();
return 0;
}
结果