紹介する
メッセージキューと共有メモリに基づくプロセス間通信の原則を習得する
実験プロジェクト
メッセージキューと共有メモリに基づくプロセス間通信
実験目的
1.プロセスの概念の理解を深め、プロセスとプログラムの違いを明確にし、同時実行の本質をさらに理解します。
2.マスタープロセス管理とプロセス通信。
3. Linuxシステムのプロセス通信メカニズム(IPC)により、任意のプロセス間で大量のデータを交換できます。
4.この実験の目的は、次のことを理解して理解することです
。5. Linuxでサポートされるメッセージ通信メカニズムとその使用方法
6. Linuxシステムの共有ストレージ領域の原理と使用方法。
実験的プレビュー
1.メッセージキュー1.メッセージキューの
概要:
メッセージキューは、リンクされたメッセージのリストであり、メモリに格納され、カーネルによって維持されます。
2.
メッセージキューの特性:メッセージキューでは、1つ以上のプロセスがメッセージを書き込んだり読み取ったりすることができ、各メッセージにはタイプがあります。
メッセージキューはメッセージのランダムクエリを実装でき、メッセージは先入れ先出しである必要はありません。順次読み取りでは、プログラミング時にメッセージのタイプに従って読み取ることができます。
名前のないパイプや有名なパイプと同様に、メッセージキューからメッセージを読み取ると、メッセージキュー内のデータは削除されます。
メッセージキュー内のメッセージもフォーマットされます。
メッセージは、カーネルが再起動されるか手動で削除されたときにのみ削除されます。メッセージキューが手動で削除されない場合、メッセージキューは常にメモリ内に存在します。
メッセージキュー識別子はメッセージを識別しますキュー。メッセージキューは全体に存在
し、システム内で一意です。
次に、共有メモリ
共有メモリを使用すると、2つ以上のプロセスで特定のストレージ領域を共有できます。
共有メモリは、プロセス間でデータを共有する最速の方法です。プロセスは共有メモリ領域にデータを書き込み、このメモリ領域を共有するすべてのプロセスはすぐに内容を見ることができます。
共有メモリの使用は、複数のプロセス間の特定のストレージ領域へのアクセスの相互排除に注意を払う必要があります。プロセスが共有メモリ領域にデータを書き込んでいる場合、このステップを完了する前に、他のプロセスがデータを読み取ったり書き込んだりしてはなりません。
試験的なコンテンツ
最初に
、メッセージキューを作成し、メッセージを送受信します。メッセージキューを作成し、msgget()、msgsnd()、msggrev()、msgctrl()およびその他の関数を呼び出して、2つのプロセス間でメッセージを送受信します。
次に、共有ストレージの
作成、接続、切断共有メモリを作成し、shmget()、shmat()、shmctl()、shmctl()などの関数を使用して、2つのプロセス間の通信を実現します。
実験装置
Windows PC
Linux Ubuntu
基本原理設計手順
まず、設計原理:
操作と観測結果を容易にするために、プログラムを「導入」として使用し、2つの子プロセス(サーバーとクライアント)をfork()関数を介して作成して通信します。
次に、メッセージキュー:
サーバーはキーが75のメッセージキューを確立し、他のプロセスから送信されるメッセージを待ちます。タイプ1のメッセージが検出されると、それは終了シグナルとして機能し、キューをキャンセルして、サーバーを終了します。メッセージを受信した後、サーバーは「(Server)received datetype(n)is:」という文を表示します。
クライアントは、キーが75のメッセージキューを使用して、タイプ10から1のメッセージを連続して送信し、終了します。最後のメッセージは、サーバーが必要とする終了信号です。クライアントがメッセージを送信するたびに、「(Client)sent datetype(n)is:」と表示され、
親プロセスはサーバーとクライアントの両方の終了後に終了します。
3.共有メモリ:
サーバーはキーが75のメッセージキューを確立し、他のプロセスから送信されるメッセージを待機します。サーバーがメッセージを受信するたびに、「(Server)received」と表示されます。
クライアントは、キーが75のメッセージキューを使用して、共有メモリ内のメッセージを受信します。クライアントがメッセージを送信するたびに、「(Client)sent」が表示され
、サーバーとクライアントの両方が終了すると親プロセスが終了します。
実験手順
まず、メッセージキュー
1.プログラムを作成し、システムコールfork()を使用して、2つの子プロセスサーバーとクライアントを作成し、親プロセスは2つの子プロセスが終了するのを待って終了します。
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
int main(int argc ,char *argv[])
{
pid_t pid;
pid = fork();
if(pid <0)
{
printf("fork error\n");
}
if(pid ==0)
{
}
else
{
pid_t pid;
pid = fork();
if(pid <0)
{
printf("fork error\n");
}
if(pid ==0)
{
}
}else{
wait(NULL);
sleep(1);
printf("Main process quit\n");
}
}
return 0;
}
2.メッセージキューのメッセージフォーマット構造を作成します。
typedef struct _msg
{
long msgtype;
char m[500];
}MSG;
3.クライアント側で、キー値75のメッセージキューを作成し、初期値が「abcdefghij」の文字列をループで10回送信します。送信するたびに、ポインターは1ビットずつシフトされ、コンテンツが送信されるたびに異なる効果が得られます。同時に、送信された各メッセージのメッセージタイプは10から1に減らされます。メッセージタイプ1のメッセージが送信されると、クライアント側が終了します。
if(pid ==0)
{
int msgqid;
int i = 0;
msgqid = msgget(75,IPC_CREAT|0666);
MSG msg;
memset(msg.m,0,sizeof(msg.m));
msg.msgtype = 10;
char *a = "abcdefghij";
for(;i < 11;i++)
{
strcpy(msg.m,a);
sleep(1);
msgsnd(msgqid,&msg,sizeof(msg.m),0);
printf("(Client)sent datetype %ld: %s\n",msg.msgtype,msg.m);
msg.msgtype--;
a++;
if(msg.msgtype == 0 )
{
sleep(1);
printf("Client sent over and shutdown now\n");
exit(0);
}
}
}
4.サーバー側で、キー値75のメッセージキューを作成し、メッセージキューからリアルタイムでメッセージを受信します。受信したメッセージタイプは、10から1に減少します。メッセージタイプ1のメッセージを受信すると、メッセージキューは破棄されます。サーバー側終了します。
if(pid ==0)
{
int msgqid;
int type = 10;
msgqid = msgget(75,IPC_CREAT|0666);
MSG msg;
while(1)
{
msgrcv(msgqid,&msg,sizeof(msg.m),type,0);
printf("\t\t\t\t\t(Server)receiveddatetype %d: %s\n",type,msg.m);
type--;
if(type == 0)
{
msgctl(msgqid,IPC_RMID,NULL);
sleep(1);
printf("Sever get type 1 date and shutdown \n");
sleep(1);
printf("message queue destroyed\n");
sleep(2);
exit(0);
}
}
5.ランニング効果は次のとおりです。
第二に、共有メモリ
- プログラムを作成し、システムコールfork()を使用して2つの子プロセスサーバーとクライアントを作成します。親プロセスは2つの子プロセスが終了して終了するのを待ちます。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <string.h>
#define BUF 2048
int main(int argc,char *argv[])
{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fork error\n");
}
if(pid == 0)
{
}
else{
pid_t pid;
pid = fork();
if(pid < 0)
{
perror("fork error\n");
}
if(pid == 0)
{
}
else{
wait(NULL);
sleep(2);
printf("Process quit\n");
}
}
return 0;
}
- クライアント側で、キー値75、サイズ2048の読み取りおよび書き込み可能な共有メモリを作成します。共有メモリがマップされた後、初期値「5201314」の文字列がループで10回送信され、毎回ポインタが送信されます。コンテンツが送信されるたびに異なる効果を得るには、1ビット戻ります。コンテンツが「4」のメッセージが送信されるまで、クライアントエンドは自然に終了します。
if(pid == 0)
{
int shmid;
int i = 0;
char *a = "5201314";
shmid = shmget(75,BUF,SHM_R|SHM_W|IPC_CREAT);
char *shmadd;
shmadd = shmat(shmid,NULL,0);
bzero(shmadd,BUF);
for(;i < 7;i++){
sleep(1);
bzero(shmadd,BUF);
strcpy(shmadd,a);
printf("(Client) sent: %s\n",shmadd);
a++;
}
}
3.サーバー側とクライアント側で、キー値75、サイズ2048の読み取りと書き込みが可能な共有メモリを作成します。共有メモリがマップされた後、共有メモリでクライアントから送信されたメッセージはリアルタイムで受信され、受信が完了したときに「4」の内容のメッセージの後に、共有メモリのマップを解除し、共有メモリを破棄して、プロセスを終了します。
if(pid == 0)
{
int shmid;
shmid = shmget(75,BUF,SHM_R|SHM_W|IPC_CREAT);
char *shmadd;
shmadd = shmat(shmid,NULL,0);
bzero(shmadd,BUF);
while(1){
sleep(1);
printf("\t\t\t\t(Server) received: %s\n",shmadd);
if(*shmadd == '4')
{
exit(0);
}
}
shmdt(shmadd);
shmctl(shmid,IPC_RMID,NULL);
}
4.ランニング効果は次のとおりです。
分析経験
分析:プロセスの作成と制御、メッセージキューの作成と関連する関数呼び出し、共有メモリの作成と関連する関数呼び出しの原則を習得している限り、それぞれの通信原則に従って段階的にそれらを完了することができます。 。
経験:この実験の実践的な操作を通じて、Linuxアプリケーションの設計は確かに操作性の高いコースであることに気付きました。実践的な操作は、教科書の理論的知識を検証して習得し、Ubuntuの理解を深め、それに精通することです操作を実行するための最良の方法は、個人操作を通じてメッセージキューと共有メモリに関連する操作原理を体験し、多くを獲得することです。これは、将来の学習のための強固な基盤を築きます。
実験結果
テスト結果が成功すると、プロセスの作成と制御、メッセージキューとプロセス間通信の作成、およびプロセス間通信での共有メモリの作成がすべて正常に実行されました。