Linuxリモート開発-(IPC通信)共有メモリの使用

コンテンツ

I.はじめに

第二に、共有メモリとは何ですか

第三に、共有メモリの作成と使用

1. shmget()関数

2. shmat()関数

3. shmdt()関数

第4に、共有メモリを使用してプロセス間通信を実現します

1.書き込み終了を準備します

2.リーダーを準備します

3.テスト結果


I.はじめに

        プロセス間通信(IPC、プロセス間通信)とは、異なるます。現在、Linuxで使用されているプロセス間通信方法は、(1)パイプ(パイプ)と名前付きパイプ(FIFO)(2)信号(信号)(3)メッセージキュー(4)共有メモリ(5)セマフォ(6)ソケット(ソケット)。

        シグナルとパイプは以前に紹介されましたが、今日は共有メモリがプロセス間でどのように通信するかを学びましょう。

第二に、共有メモリとは何ですか

  • 共有メモリ図

ソース画像を表示

        共有メモリは、プロセス用にIPCによって作成された特別なアドレス範囲であり、プロセスのアドレス空間に表示されます。他のプロセスは、同じ共有メモリセグメントを独自のアドレス空間に「接続」できます。図1に示すように。

ノート:

:共有メモリはプロセスによって作成できますが、共有メモリはどのプロセスにも属していません

:共有メモリはオペレーティングシステムに属し、オペレーティングシステムによって管理されます

すべてのプロセスは、mallocが割り当てられているかのように共有メモリアドレスにアクセスできます

:プロセスがこの共有メモリにデータを書き込む場合、変更は同じ共有メモリにアクセスできる他のプロセスによってすぐに確認されます

  • Linuxターミナルでコマンドを入力します。ipcsは、現在のシステムのメッセージキュー、共有メモリセグメント、および信号番号グループを表示できます。

        以前に使用された名前付きパイプFIFOの最大転送サイズは65535バイトであり、使用されたfifo「ファイル」はユーザーによって簡単に削除されるため、プロセス間の通信エラーが発生します。共有メモリにより、2つの無関係なプロセスが論理メモリは非常に効率的であるため、共有メモリがどのように作成され、コードで使用されるかを紹介しましょう。

第三に、共有メモリの作成と使用

1. shmget()関数

  • 機能:共有メモリを作成する(存在しない)か、共有メモリを取得する(存在する)。

#include <sys / ipc.h>
#include <sys / shm.h>

関数プロトタイプ

int shmget(key_t key、size_t size、int shmflg);

パラメータ

キー:(ゼロ以外の整数)、共有メモリセグメントに効果的に名前を付けます

サイズ:共有する必要のあるメモリの量

shmflg:9つの許可フラグで構成され、それらの使用法はファイルの作成時に使用されるモードフラグと同じです。

戻り値

共有メモリが正常に作成されると、負でない整数、つまり共有メモリのこのセグメントの識別コードが返されます。

失敗すると-1を返します。

 例:

  • 共有メモリを作成する
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>

using namespace std;

int main()
{
	int shmid = 0;
	//不存在则创建共享内存,存在则获取
	shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
	if (shmid < 0)
	{
		perror("shmget error");
	}
	else
	{
		cout << "创建共享内存成功" << endl;
	}

	return 0;
}
  • コマンド:ipcsを使用すると、777のアクセス許可と10086のバイト数で新しく作成された共有メモリセグメントを確認できます。

  • ipcrm-mshmid共有メモリを削除します
  • Ipcrm -aは、システムのルートによって最初に作成されたメモリセグメントを除くすべてを削除します

ipcrmコマンドを使用して、前の手順で作成した共有メモリを削除します 

2. shmat()関数

  • 機能:共有メモリを初めて作成するときは、どのプロセスからもアクセスできません。shmat()関数の機能は、共有メモリへのアクセスを開始し、共有メモリを現在のアドレス空間に接続することです。処理する。

#include <sys / types.h>
#include <sys / shm.h>

関数プロトタイプ

void * shmat(int shmid、const void * shmaddr、int shmflg);

パラメータ

shmid:shmget()関数によって返される共有メモリ識別子

shmaddr:現在のプロセスに接続されているときに共有メモリが配置されるアドレス

shmflg:0として指定できます。

戻り値

成功:ポインタを返します。ポインタは共有メモリの最初のバイトを指します。これは共有メモリの最初のアドレスです。

失敗:-1が返されます。

3. shmdt()関数

  • 機能:共有メモリを現在のプロセスから分離します

#include <sys / types.h>
#include <sys / shm.h>

関数プロトタイプ

int shmdt(const void * shmaddr);

パラメータ

shmaddr:shmat()関数によって返されるアドレスポインタ

戻り値

成功:0を返し、

失敗:-1を返します。

ノート:

:shmdt()関数を使用して共有メモリから抜け出すことは、共有メモリを削除することを意味するのではなく、現在のプロセスが共有メモリにアクセスできなくなることを意味します。

第4に、共有メモリを使用してプロセス間通信を実現します

以下は、共有メモリを使用して、2つの無関係なプロセス間の単純な通信を実装するための小さな例です。

1.書き込み終了を準備します

  • 共有メモリにデータを書き込みます。書き込まれるデータは{"10001"、"admin"}です。
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
using namespace std;

typedef struct student
{
	char id[10];
	char name[10];
}STU;

int main()
{
	STU stu = { "10001","admin" };
	void* shamdaddr = NULL;
	int shmid = 0;
	//不存在则创建共享内存,存在则获取
	shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
	if (shmid < 0)
	{
		perror("shmget error");
	}
	else
	{
		//连接共享内存,首地址存到 shamdaddr
		shamdaddr = shmat(shmid, NULL, 0);
		memcpy(shamdaddr, &stu, sizeof(STU));//内存拷贝 即:将stu结构体的数据写入共享内存中
		cout << "写入数据成功" << endl;
		//结束连接 当前进程脱离共享内存
		shmdt(shamdaddr);
	}
	return 0;
}

2.リーダーを準備します

  • 共有メモリからデータを読み取り、空の構造に保存します。
#include <iostream>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <string.h>
using namespace std;

typedef struct student
{
	char id[10];
	char name[10];
}STU;

int main()
{
	STU stu = { 0 };
	void* shamdaddr = NULL;
	int shmid = 0;
	//不存在则创建共享内存,存在则获取
	shmid = shmget((key_t)1001, 10086, IPC_CREAT | 0777);
	if (shmid < 0)
	{
		perror("shmget error");
	}
	else
	{
		//连接共享内存,首地址存到 shamdaddr
		shamdaddr = shmat(shmid, NULL, 0);
		memcpy(&stu, shamdaddr, sizeof(stu)); //内存拷贝 即:将共享内存中的数据写入空的结构体中
		cout << "获取数据成功" << endl;
		cout << stu.id << endl;
		cout << stu.name << endl;
		//结束连接 当前进程脱离共享内存
		shmdt(shamdaddr);
	}
	return 0;
}

 2つのプロジェクトのコードは似ていますが、一方がデータを書き込み、もう一方がデータを読み取るという違いがあります。

3.テスト結果

  • Linuxでg++によってコンパイルされ、。/モードで実行された場合、テスト結果は次のようになります。

通常の読み取りと書き込み 

共有メモリセグメントも正常に作成され、プログラムが終了したため、接続数は0になります。

共有メモリ内のデータは常に変更なしで存在し、コンテンツを繰り返し読み取ることができます。

オリジナリティは簡単ではありません。転載の際は出典をお知らせください。

役に立ったら、3回クリックすると、継続的に更新されます(hee hee)。

おすすめ

転載: blog.csdn.net/wmcy123/article/details/123718935