消息队列原理:
消息队列是在内核空间创建消息队列(msgget),进程通过特定的函数msgsnd向消息队列中存放消息,存放的形式是结构体类型的,进程通过特定的函数msgrcv从消息队列中获取消息,即消息队列中需被取走的消息从消息队列中进入进程,且消息队列中不存在该消息了。
共享内存:
是将物理内存映射到不同进程中,且在内核中形成共享内存段,不同进程直接对映射出来的共享内存进行操作,无需用户空间和内核空间切换。
#include
struct msgbuf
{
long mtype;
char mtext[1024];
};
#define M (sizeof(struct msgbuf)-sizeof(long))
void handle(int signum)
{
if(signum==SIGCHLD)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
int main(int argc, const char *argv[])
{
//回收子进程
if(signal(SIGCHLD,handle)==SIG_ERR)
{
perror("signal error");
return -1;
}
//创建一个无名管道
int pipefd[2];
if(pipe(pipefd)!=0)
{
perror("pipe error");
return -1;
}
//定义key值
key_t key;
if((key=ftok("./",'a'))==-1)
{
perror("ftok error");
return -1;
}
//创建消息队列
int mspid;
if((mspid=msgget(key,IPC_CREAT|0664))==-1)
{
perror("msgget erroor");
return -1;
}
//定义容器
struct msgbuf buf;
//判断是否要存入数据
//创建子进程
pid_t pid=fork();
if(pid>0)
{
//父进程发送消息
close(pipefd[0]);
while(1)
{
char flag;
printf("是否要存入数据y/n:");
flag=fgetc(stdin);
write(pipefd[1],&flag,1);
if(flag=='y'||flag=='Y')
{
printf("要存入的类型:");
scanf("%ld",&buf.mtype);
getchar();
printf("要存入的数据:");
fflush(stdout);
fgets(buf.mtext,sizeof(buf.mtext),stdin);
buf.mtext[strlen(buf.mtext)-1]='\0';
msgsnd(mspid,&buf,M,0); //存入消息
printf("发送成功!\n");
}
else
{
sleep(1);
}
if(strcmp(buf.mtext,"quit")==0)
{
break;
}
}
close(pipefd[1]);
}else if(pid==0)
{
//子进程读取消息
long ty;
close(pipefd[1]);
while(1)
{
char flag;
read(pipefd[0],&flag,1);
if(flag=='n'||flag=='N')
{
printf("要读取的消息类型:");
scanf("%ld",&ty);
getchar();
msgrcv(mspid,&buf,M,ty,0);
printf("收到消息:%s \n",buf.mtext);
}
if(strcmp(buf.mtext,"quit")==0)
{
break;
}
}
close(pipefd[0]);
exit(EXIT_SUCCESS);
}else
{
perror("fork error");
return -1;
}
if(msgctl(mspid,IPC_RMID,NULL)==-1)
{
perror("msgctl error");
return -1;
}
return 0;
}
#include
struct msgbuf
{
long mtype;
char mtext[1024];
};
#define M (sizeof(struct msgbuf)-sizeof(long))
void handle(int signum)
{
if(signum==SIGCHLD)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
int main(int argc, const char *argv[])
{
//回收子进程
if(signal(SIGCHLD,handle)==SIG_ERR)
{
perror("signal error");
return -1;
}
//创建一个无名管道
int pipefd[2];
if(pipe(pipefd)!=0)
{
perror("pipe error");
return -1;
}
//定义key值
key_t key;
if((key=ftok("./",'a'))==-1)
{
perror("ftok error");
return -1;
}
//创建消息队列
int mspid;
if((mspid=msgget(key,IPC_CREAT|0664))==-1)
{
perror("msgget erroor");
return -1;
}
//定义容器
struct msgbuf buf;
//判断是否要存入数据
//创建子进程
pid_t pid=fork();
if(pid==0)
{
//子进程发送消息
close(pipefd[0]);
while(1)
{
char flag;
printf("是否要存入数据y/n:");
flag=fgetc(stdin);
write(pipefd[1],&flag,1);
if(flag=='y'||flag=='Y')
{
printf("要存入的类型:");
scanf("%ld",&buf.mtype);
getchar();
printf("要存入的数据:");
fflush(stdout);
fgets(buf.mtext,sizeof(buf.mtext),stdin);
buf.mtext[strlen(buf.mtext)-1]='\0';
msgsnd(mspid,&buf,M,0); //存入消息
printf("发送成功!\n");
}else
{
sleep(1);
}
if(strcmp(buf.mtext,"quit")==0)
{
break;
}
}
close(pipefd[1]);
exit(EXIT_SUCCESS);
}else if(pid>0)
{
//父进程读取消息
long ty;
close(pipefd[1]);
while(1)
{
char flag;
read(pipefd[0],&flag,1);
if(flag=='n'||flag=='N')
{
printf("要读取的消息类型:");
scanf("%ld",&ty);
getchar();
msgrcv(mspid,&buf,M,ty,0);
printf("收到消息:%s\n",buf.mtext);
}
if(strcmp(buf.mtext,"quit")==0)
{
break;
}
}
close(pipefd[0]);
}else
{
perror("fork error");
return -1;
}
if(msgctl(mspid,IPC_RMID,NULL)==-1)
{
perror("msgctl error");
return -1;
}
return 0;
}
#include
//定义信号处理函数
void handler(int signum)
{
if(signum == SIGINT) //表明要处理2号信号
{
printf("用户按下了ctrl + c键\n");
}
if(signum == SIGTSTP) //处理暂停信号
{
printf("用户按下了ctrl + z键\n");
}
}
int main(int argc, const char *argv[])
{
//将SIGINT信号捕获
if(signal(SIGINT, handler) == SIG_ERR)
{
perror("signal error");
return -1;
}
//绑定SIGTSTP信号 ctrl + z
if(signal(SIGTSTP, handler) == SIG_ERR)
{
perror("signal error");
return -1;
}
while(1)
{
sleep(1);
printf("我真的还想再活五百年\n");
}
return 0;
}
#include
#define M 4096
int main(int argc, const char *argv[])
{
//创建key值
key_t key=ftok("./",'t');
if(key==-1)
{
perror("ftok error");
return -1;
}
//创建共享内存段
int shmid=shmget(key,M,IPC_CREAT|0664);
if(shmid==-1)
{
perror("shmget error");
return -1;
}
//将共享内存段地址映射到用户空间
char *addr=shmat(shmid,NULL,0);
if(addr==(void *)-1)
{
perror("shmat error");
return -1;
}
//操作共享内存
while(1)
{
fgets(addr,M,stdin);
addr[strlen(addr)-1]='\0';
if(strcmp(addr,"quit")==0)
{
break;
}
}
//取消共享内存
if(shmdt(addr)==-1)
{
perror("shmdt error");
return -1;
}
//删除共享内存段
if(shmctl(shmid,IPC_RMID,NULL)==-1)
{
perror("shmctl error");
return -1;
}
return 0;
}
#include
#define M 4096
int main(int argc, const char *argv[])
{
//创建key值
key_t key=ftok("./",'t');
if(key==-1)
{
perror("ftok error");
return -1;
}
//创建共享内存段
int shmid=shmget(key,M,IPC_CREAT|0664);
if(shmid==-1)
{
perror("shmget error");
return -1;
}
//将共享内存段地址映射到用户空间
char *addr=shmat(shmid,NULL,0);
if(addr==(void *)-1)
{
perror("shmat error");
return -1;
}
//操作共享内存
while(1)
{
printf("共享内存段内容:%s\n",addr) ;
sleep(1);
if(strcmp(addr,"quit")==0)
{
break;
}
}
//取消共享内存
if(shmdt(addr)==-1)
{
perror("shmdt error");
return -1;
}
//删除共享内存段
if(shmctl(shmid,IPC_RMID,NULL)==-1)
{
perror("shmctl error");
return -1;
}
return 0;
}