1、实验目的
1.1了解Linux进程通信的概念。
1.2 掌握Linux进程通信的常用方法。
2、实验内容
创建admin用户,密码也是admin。
用admin登陆后,创建src目录,所有的源代码、中间代码和目标代码都放在/home/admin/src目录下。
(1)编写一个程序创建子进程,子进程循环打印一行提示文字,父进程等待10秒钟后向子进程发送SIGKILL信号,杀死子进程。
#include<stdio.h>
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>
#include<stdlib.h>
int main()
{
pid_t result;
int ret;
result=fork();
if(result<0)
{
perror("create fault!");
exit(1);
}
else if(result==0)
{
while(1)
{
printf("this is son process PID:%d\n",getpid());
}
}
else
{
sleep(10);
if(ret=kill(result,SIGKILL)==0)
{
printf("\nthis is father process PID %d\n",getpid());
}
else
{
perror("function kill ERROR !");
}
}
return 0;
}
结果:
(2)编写一个程序创建子进程,父子进程之间通过低级管道通信,父进程循环向子进程发送一个整数,子进程把整数加1后在发送给父进程。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>
int main()
{
pid_t result;
int num[1]={10};
int pipe1[2],pipe2[2];
int buf1[1],buf2[1];
int i;
memset(buf1,0,sizeof(buf1));
memset(buf2,0,sizeof(buf2));
if(pipe(pipe1)<0)
{
printf("create pipe 1 ERROR !");
//return -1;
}
if(pipe(pipe2)<0)
{
printf("create pipe 2 ERROR !");
}
result=fork();
if(result<0)
{
perror("create son process ERROR !");
}
else if(result==0)
{
close(pipe1[1]);
close(pipe2[0]);
if(read(pipe1[0],buf1,1)>0)
{
printf("son process read num: %d\n",buf1[0]);
}
close(pipe1[0]);
for( i=0;i<1;i++)
{
num[i]++;
}
if(write(pipe2[1],num,1)!=-1)
{
printf("son process add 1,num: %d\n",num[0]);
}
close(pipe2[1]);
waitpid(result,NULL,0);
exit(0);
}
else
{
close(pipe1[0]);
close(pipe2[1]);
if(write(pipe1[1],num,1)!=-1)
{
printf("father process write num: %d\n",num[0]);
}
close(pipe1[1]);
waitpid(result,NULL,0);
//sleep(10);
if(read(pipe2[0],buf2,1)>0)
{
printf("father process read num: %d\n",buf2[0]);
}
close(pipe2[0]);
exit(0);
}
return 0;
}
结果:
(3)编写两个程序,通过命令管道实现两个进程之间的聊天通信,两个进程循环通过键盘接受输入的信息并发送给对方。
张三端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int i,rfd,wfd,len=0,fd_in;
char str[32];
int flag,stdinflag;
fd_set write_fd,read_fd;
struct timeval net_timer;
mkfifo("fifo1",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
mkfifo("fifo2",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
wfd=open("fifo1",O_WRONLY);
rfd=open("fifo2",O_RDONLY);
if(rfd<=0||wfd<=0)
return 0;
printf("this is zhangsan !\n");
while(1)
{
FD_ZERO(&read_fd);
FD_SET(rfd,&read_fd);
FD_SET(fileno(stdin),&read_fd);
net_timer.tv_sec=5;
net_timer.tv_usec=0;
memset(str,0,sizeof(str));
if(i=select(rfd+1,&read_fd,NULL,NULL,&net_timer)<0)
continue;
if(FD_ISSET(rfd,&read_fd))
{
read(rfd,str,sizeof(str));
printf("lisi: %s\n",str);
}
if(FD_ISSET(fileno(stdin),&read_fd))
{
fgets(str,sizeof(str),stdin);
len=write(wfd,str,strlen(str));
}
}
close(rfd);
close(wfd);
}
李四端:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int i,rfd,wfd,len=0,fd_in;
char str[32];
int flag,stdinflag;
fd_set write_fd,read_fd;
struct timeval net_timer;
mkfifo("fifo1",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
mkfifo("fifo2",S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
rfd=open("fifo1",O_RDONLY);
wfd=open("fifo2",O_WRONLY);
if(rfd<=0||wfd<=0)
return 0;
printf("this is lisi !\n");
while(1)
{
FD_ZERO(&read_fd);
FD_SET(rfd,&read_fd);
FD_SET(fileno(stdin),&read_fd);
net_timer.tv_sec=5;
net_timer.tv_usec=0;
memset(str,0,sizeof(str));
if(i=select(rfd+1,&read_fd,NULL,NULL,&net_timer)<0)
continue;
if(FD_ISSET(rfd,&read_fd))
{
read(rfd,str,sizeof(str));
printf("zhangsan: %s\n",str);
}
if(FD_ISSET(fileno(stdin),&read_fd))
{
fgets(str,sizeof(str),stdin);
len=write(wfd,str,strlen(str));
}
}
close(rfd);
close(wfd);
}
结果:
(4)编写两个程序,通过消息队列实现两个进程之间的聊天通信,两个进程循环通过键盘接受输入的信息并发送给对方。
张三端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define IPC_KEY 0x12345678
#define TYPE_S 1
#define TYPE_C 2
struct msgbuf {
long mtype;
char mtext[4028];
};
int main()
{
int msgid=-1;
msgid=msgget(IPC_KEY,IPC_CREAT | 0664);
if(msgid<0){
perror("msgget error");
return -1;
}
printf("this is zhangsan:\n");
while(1){
struct msgbuf buf;
memset(&buf,0x00,sizeof(struct msgbuf));
buf.mtype=TYPE_C;
scanf("%s\n",buf.mtext);
msgsnd(msgid,&buf,4028,0);
msgrcv(msgid,&buf,4028,TYPE_S,0);
printf("lisi:%s\n",buf.mtext);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
李四端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define IPC_KEY 0x12345678
#define TYPE_S 1
#define TYPE_C 2
struct msgbuf {
long mtype;
char mtext[4028];
};
int main()
{
int msgid=-1;
msgid=msgget(IPC_KEY,IPC_CREAT | 0664);
if(msgid<0){
perror("msgget error");
return -1;
}
printf("this is lisi:\n");
while(1){
struct msgbuf buf;
msgrcv(msgid,&buf,4028,TYPE_C,0);
printf("zhangsan:%s\n",buf.mtext);
memset(&buf,0x00,sizeof(struct msgbuf));
buf.mtype=TYPE_S;
scanf("%s\n",buf.mtext);
msgsnd(msgid,&buf,4028,0);
}
msgctl(msgid,IPC_RMID,NULL);
return 0;
}
(5)编写两个程序,通过共享内存实现两个进程之间的数据传递,数据是一个关于学生信息的结构体,结构体成员变量包括姓名(字符串),年龄(整数),成绩(float类型数组,包含10个元素)。
写操作:
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#include<string.h>
#define key 0x1234
typedef struct
{
char name[4];
int age;
float grade[10];
} student;
int main()
{
int shm_id;
int i,j;
char temp;
student *p_map;
shm_id=shmget(key,4096,IPC_CREAT);
if(shm_id==-1)
{
perror("get id ERROR !");
return -1;
}
p_map=(student*)shmat(shm_id,NULL,0);
temp='a';
for(i=0;i<10;i++)
{
temp+=1;
memcpy((*(p_map+i)).name,&temp,1);
(*(p_map+i)).age=20+i;
for(j=0;j<10;j++)
{
(*(p_map+i)).grade[j]=90+j;
}
}
if(shmdt(p_map)==-1)
perror("ERROR!");
}
读操作:
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<unistd.h>
#include<string.h>
#define key 0x1234
typedef struct
{
char name[4];
int age;
float grade[10];
} sudent;
int main()
{
int shm_id;
int i,j;
char temp;
sudent *p_map;
shm_id=shmget(key,4096,IPC_CREAT);
if(shm_id==-1)
{
perror("get id ERROR !");
return -1;
}
p_map=(sudent*)shmat(shm_id,NULL,0);
for(i=0;i<10;i++)
{
printf("name:%s\t",(*(p_map+i)).name);
printf("age:%d\t",(*(p_map+i)).age);
printf("grade:\n");
for(j=0;j<10;j++)
{
printf("%f\n",(*(p_map+i)).grade[j]);
}
printf("\n");
}
if(shmdt(p_map)==-1)
perror("ERROR!");
}