2

文字列の配列を保持するために共有メモリのセグメントをセットアップしようとしています。例として、この配列

string example[] = {"これは", "例 ", "文字列"};

次に、shmget を呼び出して、適切な量の OS 共有メモリを予約できるようにします。

shmget(IPC_PRIVATE, sizeOf(example), IPC_CREAT);//これで共有メモリ セグメントが作成されることを願っています

「キー引数は、セマフォ ID に関連付けられたアクセス値です」と書かれているこのサイトを見つけました。セマフォ ID とは何ですか。

これは g++ -Wall を使用してコンパイルされますが、チェックしているかどうかを確認する方法がわかりません。Linux の shm マニュアルによると、IPC_PRIVATE は「key_t」タイプのものを指定する必要があります。私の考えは、共有メモリを識別する方法、つまり共有メモリ名またはID番号として文字列を指定する方法が鍵になるということです。

マニュアルをよく読むと、shmget() が「shmid」を返すことがわかります。繰り返しになりますが、shmidとはint、string、pointerですか、それとも特別なタイプですか?これが共有メモリセグメントを識別する方法ですか? また、shmget() が何かを返す場合、それを何かに割り当てる必要はありませんか?

チュートリアルや概要をお勧めできれば、本当に感謝しています。上記の特定の質問に加えて、fork() コマンドから作成されるスレッドから共有メモリにアクセスする例を教えてください。

私の最終的な目標は、配列内の文字列ごとに一種の反転を実行するスレッドを生成することです。作業するチュートリアルが見つからないため、これは共有メモリと pthreads の作業を開始するためのほんの小さなタスクです。

4

1 に答える 1

1

細かい詳細をすべて説明する前に、共有メモリを介してデータを共有する際に非常に重要なことの 1 つは、共有メモリに実際に何を入れているかを理解することです。

あなたの例では、次のものがあります。

string example[] = {"This is", "An Example ", "of strings"};

おそらくこれについてあまり考えたことはありませんが、実際の文字列が「std::string」内にどのように格納されていると思いますか? この特定のケースの正確な詳細はわかりませんが、かなり典型的な実装の 1 つは次のようなものです [これは単純化されています。実際の「クラス文字列」は、basic_stringクラスを基盤として使用するテンプレート クラス宣言です]。

class string
{
    char *str;
    int len;
}

したがって、example共有メモリにコピーすると、共有メモリには 3 つのポインターと 3 つの整数が格納されます。これらのポインターは、ほぼ確実に共有メモリにないメモリを指しています...明らかに、「他のプロセス」のそのメモリアドレスは、期待したものではありません[少なくとも、文字列が一定ではなく、プロセスが文字列が作成される前にフォークされます - しかし、文字列が一定である場合、および/またはフォークが発生したときにすでにそこにある場合、共有メモリは本当に必要ありませんよね?]

これに対する典型的な解決策は、「プレーンな古いデータ」である共有メモリにのみデータを格納することです (そのため、内部にメンバ関数またはポインタを持つオブジェクトはありません)。これを実現する 1 つの方法は、データを「シリアル化」することです。これは、データをファイルに保存する場合と同じことです。

これは g++ -Wall を使用してコンパイルされますが、チェックしているかどうかを確認する方法がわかりません。Linux の shm マニュアルによると、IPC_PRIVATE は「key_t」タイプのものを指定する必要があります。私の考えは、共有メモリを識別する方法、つまり共有メモリ名として文字列を指定する方法、または ID 番号を指定する方法が鍵になるということです。

キーを指定するか、IPC_PRIVATE を使用することができます (マンページでは「不幸な名前」と説明されており、「IPC_NEW」の方が適切です)。

マニュアルをよく読むと、shmget() が「shmid」を返すことがわかります。繰り返しになりますが、shmidとはint、string、pointerですか、それとも特別なタイプですか?これが共有メモリセグメントを識別する方法ですか? また、shmget() が何かを返す場合、それを何かに割り当てる必要はありませんか?

リンク先のサイトでは、実際に次のファイルを保存する方法について説明していますshmid

int shmid;

... Several lines of code... 

if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {

始めるにはこれで十分だと思います。

于 2013-02-23T00:53:29.657 に答える