进程间的通信
目的:了解进程间通信的机制,实现进程的两种通信方式,多次执行,观察结果,并对两种通信方式进行比较。 内容:利用系统提供的通信系统调用,进行一种方式的进程通信的程序设计,并对结果进行分析,同时了解另一种通信方式,将两种方式进行比较分析。 (1)消息的创建发送和接收 使用系统调用msgget()、msgsnd()、msgrev()、msgctl()来编写长度为500字节的发送和接收程序。用一个程序先后创建两个子进程server和client,进行消息队列方式通信。由server建立消息队列,等待其他进程发来消息,当遇到类型为1的消息,则作为通信结束的信号,取消消息队列,退出。Server每接收到一个消息显示在屏幕上。 Client判断一个数据中的整数是否为素数,然后使用server建立的消息队列,将某数是否为素数的消息依次发送给server,然后退出。Client每次发送时把消息显示在屏幕上。 (2)共享存储区的创建,附接和断接 使用系统调用shmget(),shmat(),shmctl()编写一个与上面(1)中相同功能的程序。 (说明:以上函数是linux系统下,如果windows系统下实现也可以,将函数换为windows下相关函数即可) 报告要求: (1)仔细观察设计中的各种现象及出现的问题。分析产生各种现象的原因。寻找解决问题的办法。 (2)报告应至少包括带注释的程序清单、输出的结果及对各种现象的分析意见。
3p_pipe.cpp
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<sys/msg.h>
#include<errno.h>
#include<math.h>
#define MAX_TEXT 500
struct msg_st
{
long int msg_type
;
char text
[MAX_TEXT
];
};
void isPrm(char nums
[], int n
){
int num
;
num
= atoi(nums
);
if(num
<= 3){
if(num
> 1){
printf("%d is prime number\n", num
);
}
}else{
int sq
= (int)sqrt((double)num
);
for(int i
= 3; i
<= sq
; i
+=2){
if(num
% 2 == 0 || num
% i
== 0){
printf("%d is not prime number\n",num
);
}else{
printf("%d is prime number\n",num
);
}
}
}
}
void msgreceive(){
int msgid
= -1;
struct msg_st data
;
long int msgtype
= 0;
msgid
= msgget((key_t
)1234, 0666 | IPC_CREAT
);
if(msgid
== -1){
fprintf(stderr, "msgget failed width error: %d\n", errno
);
exit(EXIT_FAILURE
);
}
while(1){
if(msgrcv(msgid
, (void *)&data
, MAX_TEXT
, msgtype
, 0) == -1){
fprintf(stderr, "msgrcv failed width erro: %d", errno
);
}
printf("You wrote:%s\n", data
.text
);
isPrm(data
.text
, MAX_TEXT
);
if(strncmp(data
.text
,"1",1) == 0 && (strlen(data
.text
)-1) == 1){
break;
}
}
if(msgctl(msgid
, IPC_RMID
, 0) == -1){
fprintf(stderr, "msgctl(IPC_RMID) failed\n");
}
exit(EXIT_SUCCESS
);
}
void msgsend(){
struct msg_st data
;
char buffer
[MAX_TEXT
];
int msgid
= -1;
msgid
= msgget((key_t
)1234, 0666 | IPC_CREAT
);
if(msgid
== -1){
fprintf(stderr, "msgget failed error: %d\n", errno
);
exit(EXIT_FAILURE
);
}
while(1){
printf("Enter some number: \n");
fgets(buffer
, MAX_TEXT
, stdin);
data
.msg_type
= 1;
strcpy(data
.text
, buffer
);
if(msgsnd(msgid
, (void *)&data
, MAX_TEXT
, 0) == -1){
fprintf(stderr, "msgend failed\n");
exit(EXIT_FAILURE
);
}
if(strncmp(buffer
, "1",1) == 0 && (strlen(buffer
)-1) == 1){
break;
}
sleep(1);
}
}
int main(int argc
, char **argv
){
pid_t pid
, pid_1
, pid_2
;
int status
;
int i
;
for(i
=0;i
<2;i
++){
pid
=fork();
if(pid
==0&&i
==0){
pid_1
=getpid();
break;
}
if(pid
==0&&i
==1)
{
pid_2
=getpid();
break;
}
if(pid
==-1){
perror("fork error\n");
exit(1);
}
}
if(i
==0){
msgreceive();
}else if(i
==1){
waitpid(pid_1
, &status
, 0);
msgsend();
}else if(i
==2){
waitpid(pid_2
,&status
,0);
}
return 0;
}
3p_pipe2.c
#include<stdio.h>
#include<stddef.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/wait.h>
#include<string.h>
#include<math.h>
#define TEXT_SZ 500
struct shared_use_st
{
int written
;
char text
[TEXT_SZ
];
};
void isPrm(char nums
[], int n
){
int num
;
num
= atoi(nums
);
if(num
<= 3){
if(num
> 1){
printf("%d is prime number\n", num
);
}
}else{
int sq
= (int)sqrt((double)num
);
for(int i
= 3; i
<= sq
; i
+=2){
if(num
% 2 == 0 || num
% i
== 0){
printf("%d is not prime number\n",num
);
}else{
printf("%d is prime number\n",num
);
}
}
}
}
void shmread(){
void *shm
= NULL;
struct shared_use_st
*shared
;
int shmid
;
shmid
= shmget((key_t
)1234,sizeof(struct shared_use_st
),0666|IPC_CREAT
);
if(shmid
== -1)
{
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE
);
}
shm
= shmat(shmid
,0,0);
if(shm
== (void *)-1)
{
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE
);
}
printf("\nMemory attached at %X\n",(int)shm
);
shared
= (struct shared_use_at
*)shm
;
shared
->written
= 0;
while(1)
{
if(shared
->written
== 1)
{
printf("You wrote:%s",shared
->text
);
isPrm(shared
->text
, TEXT_SZ
);
sleep(1);
shared
->written
= 0;
if(strncmp(shared
->text
,"1",1) == 0 && (strlen(shared
->text
)-1) == 1)
{
break;
}
}
else
{
sleep(1);
}
}
if(shmdt(shm
) == -1)
{
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE
);
}
if(shmctl(shmid
,IPC_RMID
,0) == -1)
{
fprintf(stderr,"shmctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE
);
}
exit(EXIT_SUCCESS
);
}
void shmwrite(){
void *shm
= NULL;
struct shared_use_st
*shared
= NULL;
char buffer
[BUFSIZ
+ 1];
int shmid
;
shmid
= shmget((key_t
)1234,sizeof(struct shared_use_st
),0666|IPC_CREAT
);
if(shmid
== -1)
{
fprintf(stderr,"shmget failed\n");
exit(EXIT_FAILURE
);
}
shm
= shmat(shmid
,(void *)0,0);
if(shm
== (void *)-1)
{
fprintf(stderr,"shmat failed\n");
exit(EXIT_FAILURE
);
}
printf("Memory attched at %X\n",(int)shm
);
shared
= (struct shared_use_st
*)shm
;
while(1)
{
while(shared
->written
== 1)
{
sleep(1);
}
printf("Enter some text:");
fgets(buffer
,BUFSIZ
,stdin);
strncpy(shared
->text
,buffer
,TEXT_SZ
);
shared
->written
= 1;
if(strncmp(buffer
,"1",1) == 0 && (strlen(buffer
)-1) == 1)
{
break;
}
}
if(shmdt(shm
) == -1)
{
fprintf(stderr,"shmdt failed\n");
exit(EXIT_FAILURE
);
}
sleep(1);
exit(EXIT_SUCCESS
);
}
int main(){
pid_t pid
, pid_1
, pid_2
;
int status
;
int i
;
for(i
=0;i
<2;i
++){
pid
=fork();
if(pid
==0&&i
==0){
pid_1
=getpid();
break;
}
if(pid
==0&&i
==1)
{
pid_2
=getpid();
break;
}
if(pid
==-1){
perror("fork error\n");
exit(1);
}
}
if(i
==0){
shmread();
}else if(i
==1){
waitpid(pid_1
, &status
, 0);
shmwrite();
}else if(i
==2){
waitpid(pid_2
,&status
,0);
}
return 0;
}