實(shí)驗(yàn)題目:進(jìn)程通信
實(shí)驗(yàn)?zāi)康?/h2>
- 熟練使用 Linux 的 C 語(yǔ)言開(kāi)發(fā)環(huán)境
- 掌握 Linux 操作系統(tǒng)下的并發(fā)進(jìn)程間同步
- 掌握 Linux 操作系統(tǒng)下的進(jìn)程間通信
實(shí)驗(yàn)內(nèi)容
- 了解常見(jiàn)的消息通信方式:信號(hào)機(jī)制犬钢、消息隊(duì)列機(jī)制、共享內(nèi)存機(jī)制和管道機(jī)制。
- 掌握消息隊(duì)列機(jī)制中常用的系統(tǒng)調(diào)用有:建立一個(gè)消息隊(duì)列 msgget链蕊; 向消息隊(duì)列發(fā)送
消息 msgsnd突想;從消息隊(duì)列接收消息 msgrcv;取或送消息隊(duì)列控制信息 msgctl糠聪。
- 掌握管道機(jī)制中常用的系統(tǒng)調(diào)用:建立管道文件 pipe门躯;寫(xiě)操作 write僚祷,讀操作 read钻蹬。
- 了解信號(hào)機(jī)制中常用的系統(tǒng)調(diào)用吼蚁。
- 了解共享內(nèi)存機(jī)制中常用的系統(tǒng)調(diào)用。
1.共享內(nèi)存的通信方式
消息 msgsnd突想;從消息隊(duì)列接收消息 msgrcv;取或送消息隊(duì)列控制信息 msgctl糠聪。
( 1) 有兩個(gè)程序,一個(gè)是發(fā)送肝匆,一個(gè)是接收粒蜈。
發(fā)送進(jìn)程的代碼如下:
/*共享內(nèi)存的發(fā)送程序 sndshm.c,先運(yùn)行發(fā)送程序旗国,再運(yùn)行接收程序*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
int main() {
int shmid;
/*共享內(nèi)存的內(nèi)部標(biāo)識(shí)*/
char *viraddr;
/*定義附接到共享內(nèi)存的虛擬地址*/
char buffer[BUFSIZ];
/*創(chuàng)建共享內(nèi)存*/
shmid = shmget(1234, BUFSIZ, 0666|IPC_CREAT);
/*附接到進(jìn)程的虛擬地址空間*/
viraddr = (char *)shmat(shmid, 0, 0);
/*循環(huán)輸入信息枯怖,直到輸入 end 結(jié)束*/
while(1) {
puts("Enter some text:");
fgets(buffer, BUFSIZ, stdin);
strcat(viraddr, buffer);
/*追加到共享內(nèi)存*/
if(strncmp(buffer, "end", 3) ==0)
break;
}
shmdt(viraddr);
/*斷開(kāi)鏈接*/
return 0;
}
接收進(jìn)程的代碼如下:
/*共享內(nèi)存的接收進(jìn)程程序 rcvshm.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
int main() {
int shmid;
char *viraddr;
/*獲取共享內(nèi)存*/
shmid = shmget(1234, BUFSIZ, 0666|IPC_CREAT);
/*附接到進(jìn)程的虛擬地址空間*/
viraddr = (char *)shmat(shmid, 0, 0);
/*打印信息內(nèi)容*/
printf("your message is :\n %s", viraddr);
/*斷開(kāi)鏈接*/
shmdt(viraddr);
/*撤銷(xiāo)共享內(nèi)存*/
shmctl(shmid, IPC_RMID, 0);
return 0;
}
捕獲.PNG
2. 消息隊(duì)列的通信方式
( 1) 消息隊(duì)列通信方式有兩個(gè)程序,一個(gè)負(fù)責(zé)發(fā)送能曾,另一個(gè)負(fù)責(zé)接收度硝。
發(fā)送進(jìn)程代碼:
/*發(fā)送消息進(jìn)程 sndfile.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#define MAXMSG 512
/*定義消息長(zhǎng)度*/
/*定義消息緩沖區(qū)隊(duì)列中的數(shù)據(jù)結(jié)構(gòu)*/
struct my_msg {
long int my_msg_type;
char some_text[MAXMSG];
}
msg;
int main() {
int msgid;
/*定義消息緩沖區(qū)內(nèi)部標(biāo)識(shí)*/
char buffer[BUFSIZ];
/*用戶(hù)緩沖區(qū)*/
/*創(chuàng)建消息隊(duì)列*/
msgid = msgget(1234, 0666|IPC_CREAT);
/*循環(huán)向消息隊(duì)列中發(fā)送消息,直到輸入 end 結(jié)束*/
while(1) {
puts("Enter some text:");
fgets(buffer, BUFSIZ, stdin);
msg.my_msg_type = 1;
strcpy(msg.some_text, buffer);
msgsnd(msgid, &msg, MAXMSG, 0);
/*發(fā)送消息到緩沖隊(duì)列中*/
if (strncmp(msg.some_text, "end", 3) == 0)
break;
}
return 0;
}
接收進(jìn)程代碼:
/*消息隊(duì)列機(jī)制的接收程序 rcvfile.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/msg.h>
#define MAXMSG 512
struct my_msg {
long int my_msg_type;
char some_text[MAXMSG];
}
msg;
int main() {
int msgid;
long int msg_to_receive = 0;
msgid = msgget(1234, 0666|IPC_CREAT);
/*循環(huán)從消息隊(duì)列中接收消息寿冕,讀入 end 結(jié)束接收*/
while (1) {
msgrcv(msgid, &msg, BUFSIZ, msg_to_receive, 0);
printf("You wrote:%s", msg.some_text);
if (strncmp(msg.some_text, "end", 3) == 0)
break;
}
msgctl(msgid, IPC_RMID, 0);
return 0;
}
捕獲2.PNG
3. 管道通信
/*管道文件 pipe.c*/
#include <stdio.h>
#include <unistd.h>
int main() {
int p1, fd[2];
char outpipe[50];
/*定義讀緩沖區(qū)*/
char inpipe[50] = "This is a message from child!";
/*定義寫(xiě)緩沖區(qū)*/
pipe(fd);
while ((p1 = fork()) == -1);
if (p1 == 0)
/*子進(jìn)程中寫(xiě)*/ {
write(fd[1], inpipe, 50);
} else
/*父進(jìn)程中讀*/ {
wait(0);
read(fd[0], outpipe, 50);
printf("%s \n", outpipe);
}
return 0;
}
結(jié)果:
捕獲3.PNG
4.信號(hào)機(jī)制
第一個(gè)程序有信號(hào)處理機(jī)制
/*signal.c*/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void int_func(int sig);
int k;
/*定義循環(huán)變量*/
void int_func(int sig) {
k = 0;
}
int main() {
signal(SIGINT, int_func);
k = 1;
while (k == 1) {
printf("Hello, world!\n");
}
printf("OK!\n");
printf("pid: %d, ppid: %d \n", getpid(), getppid());
}
捕獲4.PNG