无名管道
对同一个管道进行操作
内核管道由队列实现—特殊的文件
open 只能创建普通文件
用pipe函数来创建文件
返回值 (文件描述符)open(文件名称,打开模式,权限)
int返回值(==0成功,=-1失败)pipe(文件描述符【2个】–fd[2])
read文件描述符fd[0],write文件描述符fd[1]
注意:
(1)管道是创建在内存中的,进程结束,空间释放,管道就不存在了
(2)管道中的东西,读完了就删了
(3) 如果管道中没有东西可读,则会阻塞
写阻塞,读阻塞
缺点:
不能实现非亲缘关系(非父子进程)之间的通信
pipe1.c
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int fd[2];
int ret;
ret=pipe(fd);
char writebuf[]="hello world!";
char readbuf[128]={0};
if(ret<0)
{
perror("create pipe error!");
exit(1);
}
printf("create pipe success fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
write(fd[1],writebuf,sizeof(writebuf));
read(fd[0],readbuf,128);
printf("readbuf=%s\n",readbuf);
memset(readbuf,0,128);
//second read from pipe
read(fd[0],readbuf,128);
printf("second read after\n");
close(fd[0]);
close(fd[1]);
return 0;
}
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int i=0;
int fd[2];
int ret;
ret=pipe(fd);
char writebuf[]="hello world!";
char readbuf[128]={0};
if(ret<0)
{
perror("create pipe error!");
exit(1);
}
printf("create pipe success fd[0]=%d,fd[1]=%d\n",fd[0],fd[1]);
while(i<100000)
{
write(fd[1],writebuf,sizeof(writebuf));
i++;
}
printf("write pipe end\n");
close(fd[0]);
close(fd[1]);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid;
int fd[2];
int ret;
char process_inter=0;
ret =pipe(fd);
if(ret<0)
{
perror("create pipe error!");
exit(1);
}
printf("create pipe success!\n");
pid =fork();
if(pid==0)
{
int i=0;
read(fd[0],&process_inter,1);
while(process_inter==0);
for(i=0;i<5;i++)
{
printf("this is child process i=%d\n",i);
usleep(100);
}
}
if(pid>0)//parent process
{
int i=0;
for(i=0;i<5;i++)
{
printf("this is parent process i=%d\n",i);
usleep(100);
}
process_inter=1;
sleep(5);
write(fd[1],&process_inter,1);
}
}
有名管道
文件系统中存在一个文件节点
文件类型:管道文件
mkfifo:创建管道文件
返回值int(=0成功,<0失败)mkfifo(文件名,权限) 和umask 有关
并没有在内核中创建管道,是通过open函数打开时在内核中生成管道
有名管道、字符设备、块设备、套接字 只有文件节点,不占磁盘空间
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
int main()
{
int ret;
ret=mkfifo("./mkfifo.txt",0777);
if(ret<0)
{
perror("create mkfifo error!");
exit(1);
}
printf("create mkfifo success!\n");
return 0;
}
firstmkfifo.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
int fd;
char process_inter=0;
fd=open("./mkfifo.txt",O_WRONLY);
if(fd<0)
{
perror("open file error!");
exit(1);
}
printf("open file success!\n");
for(int i=0;i<5;i++)
{
printf("this is first process i=%d\n",i);
usleep(100);
}
process_inter=1;
sleep(3);
write(fd,&process_inter,1);
while(1);
return 0;
}
secondmkfifo.c
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main()
{
int fd;
char process_inter=0;
fd=open("./mkfifo.txt",O_RDONLY);
if(fd<0)
{
perror("open file error!");
exit(1);
}
printf("open file success!\n");
read(fd,&process_inter,1);
while(process_inter==0);
for(int i=0;i<5;i++)
{
printf("this is second process i=%d\n",i);
usleep(100);
}
while(1);
return 0;
}
信号通信
信号的对象在内核中已经存在
内核中有很多信号
通过kill -l 查看有多少种信号
1)信号发送 kill(可以发送给任意进程) raise (只能向当前进程发送信号) alarm(只能发一种信号:闹钟信号SIGALRM,定时一段时间才发信号,只能发送给当前进程)
2)信号接收pause() sleep while(1)
3)信号处理signal
int(=0成功,=-1失败) kill(进程号,信号)
例:kill (1111,9)//要转换
int raise(信号)
unsigned int alarm(unsigned int seconds:指定秒数)
int(==0成功) pause(void);使之睡眠,相当于sleep,但这个可以一直睡眠
void(*signal(int signum,void(*handler)(int)))(int);
A=void(*handler)(int)):函数指针变量,函数的形式:含有一个整型参数,无返回值的函数
void(*signal(int signum,A(int);有两个参数
第一个参数:信号值:处理哪个信号
第二个参数:函数指针:怎样处理这个信号
三种形式:SIG_ING:忽略该信号
SIG_DFL:采用系统默认方式处理信号
自定义的信号处理函数指针
返回值:函数指针
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc,char*argv[])
{
int sig;
int pid;
if(argc<3)
{
printf("please input param\n");
return -1;
}
sig=atoi(argv[1]);
pid=atoi(argv[2]);
printf("sid=%d,pid=%d\n",sig,pid);
kill(pid,sig);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
printf("raise before\n");
raise(9);//_exit()
printf("raise after\n");
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
pid_t pid;
pid=fork();
if(pid>0)
{
sleep(8);
if(waitpid(pid,NULL,WNOHANG)==0)
{
kill(pid,9);
}
wait(NULL);
while(1);
}
if(pid==0)
{
printf("raise function before \n");
raise(SIGTSTP);
printf("raise function after\n");
exit(0);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int i=0;
printf("alarm before\n");
alarm(9);
printf("alarm after\n");
while(i<20)
{
i++;
sleep(1);
printf("process things,i=%d!\n",i);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
int i=0;
printf("pause before\n");
pause();
printf("pause after\n");
while(i<20)
{
i++;
sleep(1);
printf("process things,i=%d!\n",i);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void myfun(int signum)
{
int i=0;
while(i<10)
{
printf("process signal signum=%d\n",signum);
sleep(1);
i++;
}
return ;
}
int main()
{
int i=0;
signal(14,myfun);
printf("alarm before\n");
alarm(9);
printf("alarm after\n");
while(i<20)
{
i++;
sleep(1);
printf("process things,i=%d!\n",i);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void myfun(int signum)
{
int i=0;
while(i<10)
{
printf("process signal signum=%d\n",signum);
sleep(1);
i++;
}
return ;
}
int main()
{
int i=0;
signal(14,myfun);
printf("alarm before\n");
alarm(9);
printf("alarm after\n");
signal(14,SIG_IGN);
while(i<20)
{
i++;
sleep(1);
printf("process things,i=%d!\n",i);
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void myfun(int signum)
{
int i=0;
while(i<10)
{
printf("process signal signum=%d\n",signum);
sleep(1);
i++;
}
return ;
}
int main()
{
int i=0;
signal(14,myfun);
printf("alarm before\n");
alarm(9);
printf("alarm after\n");
signal(14,SIG_IGN);
signal(14,SIG_DFL);
while(i<20)
{
i++;
sleep(1);
printf("process things,i=%d!\n",i);
}
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void myfun(int signum)
{
int i=0;
while(i<5)
{
printf("receive signum=%d,i=%d\n",signum,i);
sleep(1);
i++;
}
return ;
}
void myfun1(int signum)
{
printf("receive signum=%d\n",signum);
wait(NULL);
return;
}
int main()
{
pid_t pid;
pid=fork();
if(pid>0)
{
int i=0;
signal(10,myfun);
signal(17,myfun1);
while(1)
{
printf("parent process things,i=%d\n",i);
sleep(1);
i++;
}
}
if(pid==0)
{
sleep(10);
kill(getppid(),10);
sleep(10);
exit(0);//kill(getppid(),17);
}
return 0;
}
共享内存
IPC通信:IPC对象{共享内存,消息队列,信号灯}–》内核空间
特点:
1)共享内存创建后,一直存在于内核中,直到被删除或系统关闭
2)共享内存和管道不一样,读取后,内容仍然在其共享内存中
1)创建或打开:shmget
int shmget(key_t key,int size,int shmflg权限);
key:1)IPC宏—>key=0,只能实现有亲缘关系的进程间的通信
2)ftok(key不一样)可以实现非亲缘关系的进程间的通信
char ftok(const char *path,char key)
第一个参数:文件路径和文件名
第二个参数:一个字符
返回值:正确返回key值,错返回-1
shmat 将共享内存映射到用户空间的地址中
void *shmat(int shmid,const void *shmaddr,int shmflg);
第一个参数:ID号
第二个参数:映射到的地址,NULL为系统自动完成的映射;
第三个参数:shmflg SHM_RDONLY共享内存只读
默认是0,表示共享内存可读写
返回值:成功:映射后的地址
失败:NULL
shmdt:将进程里的地址映射删除
int shmdt(const void* shmaddr);
参数:shmaddr共享内存映射后的地址
返回值:成功0 失败-1
shmctl:删除共享内存对象
int shmctl(int shmid,int cmd,struct shmid_ds,*buf);
参数:shmid:要操作的共享内存标识符
cmd:IPC_STAT(获取对象属性)–实现了命令ipcs-m
IPC_SET(设置对象属性)
IPC_RMID(删除对象)–实现了命令ipcrm -m
buf:指定IPC_STAT/IPC_SET时用以保存、设置属性
函数返回值: 成功 0 失败 -1
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int shmid;
shmid=shmget(IPC_PRIVATE,128,0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
system("ipcs -m");
// system("ipcrm -m shmid");
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int shmid;
int key;
key=ftok("./a.c",'a');
if(key<0)
{
perror("create key failure!");
exit(1);
}
printf("create key success! key=%d\n",key);
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
system("ipcs -m");
// system("ipcrm -m shmid");
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int shmid;
int key;
char *p;
key=ftok("./a.c",'a');
if(key<0)
{
perror("create key failure!");
exit(1);
}
printf("create key success! key=%d\n",key);
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
system("ipcs -m");
p=(char*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("shmat function failure!");
exit(1);
}
//write share memory
fgets(p,128,stdin);
//start read share memory
printf("share memory data:%s\n",p);
printf("second read memory data:%s\n",p);
// system("ipcrm -m shmid");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int shmid;
int key;
char *p;
key=ftok("./a.c",'a');
if(key<0)
{
perror("create key failure!");
exit(1);
}
printf("create key success! key=%d\n",key);
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
system("ipcs -m");
p=(char*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("shmat function failure!");
exit(1);
}
//write share memory
fgets(p,128,stdin);
//start read share memory
printf("share memory data:%s\n",p);
printf("second read memory data:%s\n",p);
shmdt(p);
// memcpy(p,"abcd",4);//用以验证已经删除
// system("ipcrm -m shmid");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int shmid;
int key;
char *p;
key=ftok("./a.c",'a');
if(key<0)
{
perror("create key failure!");
exit(1);
}
printf("create key success! key=%d\n",key);
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
system("ipcs -m");
p=(char*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("shmat function failure!");
exit(1);
}
//write share memory
fgets(p,128,stdin);
//start read share memory
printf("share memory data:%s\n",p);
printf("second read memory data:%s\n",p);
shmdt(p);
// memcpy(p,"abcd",4);//用以验证已经删除
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
// system("ipcrm -m shmid");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
int main(int argc,char*argv[])
{
int shmid;
if(argc<3)
{
printf("please input param\n");
return -1;
}
if(strcmp(argv[1],"-m")==0)
{
printf("delete share memory\n");
}
else return -2;
shmid=atoi(argv[2]);
printf("shmid=%d\n",shmid);
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
void myfun(int signum)
{
return ;
}
int main()
{
int shmid;
int key;
char *p;
int pid;
shmid=shmget(IPC_PRIVATE,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
pid=fork();
if(pid>0)
{
signal(SIGUSR2,myfun);
p=(char*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("parent process:shmat function failure!");
exit(1);
}
while(1)
{
printf("parent process start write share memory:\n");
//write share memory
fgets(p,128,stdin);
kill(pid,SIGUSR1);//child process read data
pause();
}
}
if(pid==0)
{
p=(char*)shmat(shmid,NULL,0);
if(p==NULL)
{
printf("child process shmat function failure!\n");
return -3;
}
while(1)
{
signal(SIGUSR1,myfun);
pause();//wait parent process write
//start read share memory
printf("share memory data:%s\n",p);
kill(getppid(),SIGUSR2);
}
}
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
return 0;
}
server.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
struct mybuf
{
int pid;
char buf[124];
};
void myfun(int signum)
{
return ;
}
int main()
{
int shmid;
int key;
struct mybuf *p;
int pid;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -1;
}
printf("create key success!\n");
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
signal(SIGUSR2,myfun);
p=(struct mybuf*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("parent process:shmat function failure!");
exit(1);
}
//get client pid
p->pid=getpid();//write server pid to memory
pause();//wait client read server pid;
pid=p->pid;
//white
while(1)
{
printf("parent process start write share memory:\n");
//write share memory
fgets(p->buf,128,stdin);
kill(pid,SIGUSR1);//client process read data
pause();//wait client process read
}
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
return 0;
}
client.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/shm.h>
struct mybuf
{
int pid;
char buf[124];
};
void myfun(int signum)
{
return ;
}
int main()
{
int shmid;
int key;
struct mybuf *p;
int pid;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -1;
}
printf("create key success!\n");
shmid=shmget(key,128,IPC_CREAT|0777);
if(shmid<0)
{
perror("create share memory failure!");
exit(1);
}
printf("create share memory success shmid=%d\n",shmid);
signal(SIGUSR1,myfun);
p=(struct mybuf*)shmat(shmid,NULL,0);
if(p==NULL)
{
perror("parent process:shmat function failure!");
exit(1);
}
//get server pid
//read share memory
pid=p->pid;
//write client pid to share memory
p->pid=getpid();
//kill signal
kill(pid,SIGUSR2);
//client start read data from share memory
while(1)
{
pause();//wait server write data to share memory;
printf("client process receive data from share memory:%s\n",p->buf);//read data
kill(pid,SIGUSR2);//server may write share memory
}
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
return 0;
}
消息队列
创建消息队列
int msgget(key_t key, int flag);
参数:和消息队列关联的key的值
flag:消息队列的访问权限
返回值:消息队列ID 失败-1
删除
int msgctl(int msgqid,int cmd,struct msqid_ds *buf)
参数:第一个:消息队列的队列ID
第二个:IPC_STAT:读属性,并保存在buf指定的缓冲区中
IPC_SET:设置消息队列属性,这个值取自buf参数
IPC_RMID:从系统中删除消息队列
第三个参数:消息队列缓冲区
函数返回值:成功返回 0 失败返回-1
读完就删
int msgrcv(int msgid,void*msgp,size_t size,long msgtype,int flag);
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int main()
{
int msgid;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
// system("ipcrm -m shmid");
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int main()
{
int msgid;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
//delete message queue
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int msgid;
struct msgbuf sendbuf;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
//init sendbuf
sendbuf.type=100;
printf("please input message:\n");
fgets(sendbuf.voltage,124,stdin);
//start write message to message queue
msgsnd(msgid,(void*)&sendbuf,strlen(sendbuf.voltage),0);
while(1);
//delete message queue
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int readret;
int msgid;
struct msgbuf sendbuf,recvbuf;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
//init sendbuf
sendbuf.type=100;
printf("please input message:\n");
fgets(sendbuf.voltage,124,stdin);
//start write message to message queue
msgsnd(msgid,(void*)&sendbuf,strlen(sendbuf.voltage),0);
//start read message from message queue
memset(recvbuf.voltage,0,124);
readret=msgrcv(msgid,(void*)&recvbuf,124,100,0);
printf("recv:%s\n",recvbuf.voltage);
printf("readret=%d\n",readret);
//second read message queue
// msgrcv(msgid,(void*)&recvbuf,124,100,0);
// printf("second read after!");
//delete message queue
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
实现单向通信
write.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int readret;
int msgid;
int key;
struct msgbuf sendbuf,recvbuf;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -2;
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
sendbuf.type=100;
//write message queue
while(1)
{
memset(sendbuf.voltage,0,124);//clear send buffer
printf("please input message:\n");
fgets(sendbuf.voltage,124,stdin);
//start write message to message queue
msgsnd(msgid,(void*)&sendbuf,strlen(sendbuf.voltage),0);
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
read.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int readret;
int msgid;
int key;
struct msgbuf sendbuf,recvbuf;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -2;
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
//read message queue
while(1)
{
memset(recvbuf.voltage,0,124);//clear recv buffer
//start read message from message queue
msgrcv(msgid,(void*)&recvbuf,124,100,0);
printf("recvive data from message queue:%s\n",recvbuf.voltage);
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
实现双向通信
msgserver.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int readret;
int msgid;
int key;
int pid;
struct msgbuf sendbuf,recvbuf;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -2;
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
pid=fork();
if(pid>0)//parent process write 100
{
sendbuf.type=100;
//write message queue
while(1)
{
memset(sendbuf.voltage,0,124);//clear send buffer
printf("please input message:\n");
fgets(sendbuf.voltage,124,stdin);
//start write message to message queue
msgsnd(msgid,(void*)&sendbuf,strlen(sendbuf.voltage),0);
}
}
if(pid==0)//child process read 200
{
while(1)
{
memset(recvbuf.voltage,0,124);
msgrcv(msgid,(void *)&recvbuf,124,200,0);
printf("receive message from message queue:%s\n",recvbuf.voltage);
}
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
msgclient.c
#include<string.h>
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
struct msgbuf
{
long type;
char voltage[124];
char ID[4];
};
int main()
{
int readret;
int msgid;
int key;
int pid;
struct msgbuf sendbuf,recvbuf;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -2;
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
perror("create message queue failure!");
exit(1);
}
printf("create message queue success msgid=%d\n",msgid);
system("ipcs -q");
pid=fork();
if(pid==0)//child process write 200
{
sendbuf.type=200;
//write message queue
while(1)
{
memset(sendbuf.voltage,0,124);//clear send buffer
printf("please input message:\n");
fgets(sendbuf.voltage,124,stdin);
//start write message to message queue
msgsnd(msgid,(void*)&sendbuf,strlen(sendbuf.voltage),0);
}
}
if(pid>0)//parent process read 100
{
while(1)
{
memset(recvbuf.voltage,0,124);
msgrcv(msgid,(void *)&recvbuf,124,100,0);
printf("receive message from message queue:%s\n",recvbuf.voltage);
}
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
信号灯
信号灯和信号量区别:
信号量:单个信号量
信号灯:信号量的集合
这里面的函数都是针对集合
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
创建:
int semget(key_t key,int nsems,int semflg)
参数:
第一个:和信号灯集有关的key值
第二个:信号灯集中包含的信号灯数目
第三个:信号灯集合的访问权限
返回值:成功返回信号灯集ID,错-1
删除、初始化
int semctl(int semid,int semnum,int cmd,…union semun arg(不是地址));
参数:semid:信号灯集ID
semnum:要修改的信号灯编号
cmd:GETVAL:获取信号灯的值
SETVAL:设置信号灯的值
IPC_RMID:从系统中删除信号灯集合
返回值:成功0 失败-1
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
int main()
{
int semid;
semid=semget(IPC_PRIVATE,3,0777);
if(semid<0)
{
perror("create semaphore failure!");
exit(1);
}
printf("create semaphore success semid=%d\n",semid);
system("ipcs -s");
// system("ipcrm -m shmid");
return 0;
}
#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
int main()
{
int semid;
semid=semget(IPC_PRIVATE,3,0777);
if(semid<0)
{
perror("create semaphore failure!");
exit(1);
}
printf("create semaphore success semid=%d\n",semid);
system("ipcs -s");
//delete semaphore
semctl(semid,0,IPC_RMID,NULL);
system("ipcs -s");
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
#include<semaphore.h>
sem_t sem;
void* fun(void *var)//child thread code
{
int j;
//p wait
sem_wait(&sem);//sleep
for(j=0;j<10;j++)
{
// usleep(100);
printf("this is fun j=%d\n",j);
}
}
int main()//main thread code
{
int i;
char str[]="hello linux\n";
pthread_t tid;
int ret;
sem_init(&sem,0,0);//sem=0
ret=pthread_create(&tid,NULL,fun,(void*)str);
if(ret<0)
{
perror("create pthread error!");
exit(1);
}
for(i=0;i<10;i++)
{
usleep(100);
printf("this is main fun i=%d\n",i);
}
sem_post(&sem);
while(1);
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int semid;
union semun mysemun;
struct sembuf mysembuf;
void* fun(void *var)//child thread code
{
int j;
//p wait
mysembuf.sem_op=-1;
semop(semid,&mysembuf,1);
for(j=0;j<10;j++)
{
// usleep(100);
printf("this is fun j=%d\n",j);
}
}
int main()//main thread code
{
int i;
char str[]="hello linux\n";
pthread_t tid;
int ret;
semid=semget(IPC_PRIVATE,3,0777);
if(semid<0)
{
printf("create semaphore failure!\n");
return -1;
}
printf("create semaphore success,semid=%d\n",semid);
system("ipcs -s");
mysemun.val=0;
semctl(semid,0,SETVAL,mysemun);
mysembuf.sem_num=0;
mysembuf.sem_flg=0;
ret=pthread_create(&tid,NULL,fun,(void*)str);
if(ret<0)
{
perror("create pthread error!");
exit(1);
}
for(i=0;i<10;i++)
{
usleep(100);
printf("this is main fun i=%d\n",i);
}
//v
mysembuf.sem_op=1;
semop(semid,&mysembuf,1);
while(1);
return 0;
}
下面这个先运行客户端,在运行服务器
semclient.c
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int semid;
union semun mysemun;
struct sembuf mysembuf;
int main()//main thread code
{
int i;
int key;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -3;
}
printf("create key success!\n");
semid=semget(key,3,IPC_CREAT|0777);
if(semid<0)
{
printf("create semaphore failure!\n");
return -1;
}
printf("create semaphore success,semid=%d\n",semid);
system("ipcs -s");
//init sem
mysemun.val=0;
semctl(semid,0,SETVAL,mysemun);
mysembuf.sem_num=0;
mysembuf.sem_flg=0;
//P wait
mysembuf.sem_op=-1;
semop(semid,&mysembuf,1);
for(i=0;i<10;i++)//second
{
usleep(100);
printf("this is client fun i=%d\n",i);
}
//v
// mysembuf.sem_op=1;
// semop(semid,&mysembuf,1);
while(1);
return 0;
}
semserver.c
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<unistd.h>
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
};
int semid;
union semun mysemun;
struct sembuf mysembuf;
int main()//main thread code
{
int i;
int key;
key=ftok("./a.c",'a');
if(key<0)
{
printf("create key failure!\n");
return -3;
}
printf("create key success!\n");
semid=semget(key,3,IPC_CREAT|0777);
if(semid<0)
{
printf("create semaphore failure!\n");
return -1;
}
printf("create semaphore success,semid=%d\n",semid);
system("ipcs -s");
//init sem
mysemun.val=0;
semctl(semid,0,SETVAL,mysemun);
mysembuf.sem_num=0;
mysembuf.sem_flg=0;
for(i=0;i<10;i++)//first
{
usleep(100);
printf("this is server fun i=%d\n",i);
}
//v
mysembuf.sem_op=1;
semop(semid,&mysembuf,1);
while(1);
return 0;
}