コンピュータオペレーティングシステムの基礎(16)---プロセス同期用の共有メモリ

前書き

これは第16章、プロセス同期用の共有メモリです以前の紹介はすべてスレッド同期を解決する方法ですが、この記事はプロセス同期を処理する方法です-共有メモリ

共有メモリ

スレッドの同期

各プロセスには1つ以上のスレッドがあります。スレッドはプロセスリソースを共有し、スレッド間の通信も必要です。または、一部のプロセスリソースの状態をスレッド間で同期する必要があります。この場合、スレッド間の情報の同期が必要です。

プロセスの同期

オペレーティングシステムには1つ以上のプロセスが存在する場合があります。プロセスはコンピュータリソース(メモリ、ディスクなどを含む)を共有します。したがって、プロセス間で情報の同期も必要です。前の記事で述べた生産者/消費者問題と哲学者の食事の問題はすべてプロセス同期の理由です

この記事で共有メモリを学習する前に、前述のオペレーティングシステムがプロセス管理をどのように実行するかを確認してください。
各プロセスには独自のプロセススペースがあり、それらのプロセススペースはセグメントページストレージ管理を介してマッピングされ、実際のメモリはページテーブルを介してマッピングされます。プロセス間のプロセススペースは互いに干渉せず、互いに独立しています。

したがって:

  • ある程度、複数のプロセスが物理メモリを一緒に使用します(つまり、複数のプロセスが物理メモリを共有します)
  • オペレーティングシステムのプロセス管理により、プロセス間のメモリスペースは独立しているため(つまり、2つのプロセスの論理メモリスペースは完全に無関係です)、各プロセスの独立した操作の安全性保証されます(これもプロセス管理の機能)

デフォルトでは、プロセスはプロセス空間外のメモリ空間にアクセスできません(つまり、あるプロセスが別のプロセスのメモリ空間にアクセスできません)。

ただし、共有メモリはこの制限を破ることができます。共有メモリを介して、プロセスはページテーブルを介して同じメモリにマップできます。このメモリはプロセス1またはプロセス2で使用できます。つまり、この共有メモリはプロセス1で読み取りまたは書き込みが可能であり、プロセス2でも読み取りまたは書き込みが可能です。したがって、共有メモリを介して、プロセス1とプロセス2が接続を確立します。次に、共有メモリもオペレーティングシステムによって提供される重要なプロセス同期方法です

共有メモリの概要

  • 共有ストレージを使用すると、無関係のプロセスが同じ物理メモリにアクセスできます(その実装の原則は、同じ物理メモリを異なるプロセスのページテーブルにマップすることです。これにより、異なるプロセスが同じ物理メモリにアクセスできます。ページテーブル)
  • 共有メモリは、2つのプロセス間でデータ共有および転送するため最速の方法です
  • 共有メモリは同期メカニズムを提供しません。同時アクセスによって引き起こされる問題を回避するために、アクセスを管理するために他のメカニズムを使用する必要があります。

注:同期メカニズム:並行プログラミングでは、各プロセスがパブリック変数へのアクセスを制限する必要があります。この制限は同期と呼ばれます。

共有メモリステップを使用する

  • 共有メモリに申し込む
  • 共有メモリをプロセススペースに接続します(プロセスがページテーブルを介して共有メモリにアクセスできるようにするため)
  • 共有メモリを使用する
  • プロセススペースを離れて削除

コード例

この例では、クライアントとサーバーがあり、それらは共有メモリを介して通信します

common.hはいくつかの公開情報を掲載しています

#ifndef __COMMON_H__
#define __COMMON_H__

//共享内存中的字符串最大长度
#define TEXT_LEN 2048 

//共享内存的数据结构
//因为在默认情况下,内存里边存储的方式是没有数据结构的,当程序需要使用共享内存的话,就需要定义数据结构,把结构数据存储到共享内存
struct ShmEntry{
    //是否可以读取共享内存,用于进程间同步
    bool can_read
    //共享内存信息
    char msg[2048]
};
#endif

server.cpp

#include "common.h"

#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <iostream>

int main()
{
    //定义共享内存结构图
    struct ShmEntry *entry;
    
    //1.申请共享内存
    int shmid = shmget((key_t)1111, sizeof(struct ShmEntry), 0666|IPC_CREAT);
    if(shmid == -1) {
        std::cout << "Create share memory error!" << std::endl;
        return -1;
    }
    
    //2.连接到当前进程空间/使用共享内存
    entry = (ShmEntry*)shmat(shmid, 0, 0);
    entry->can_read = 0;
    while(true){
        if(entry->can_read == 1) {
            std::cout<< "Received message" << entry->msg << std::endl;
            entry->can_read = 0;
        } else {
            std::cout << "Entry can not read. Sleep 1s" << std::endl;
            sleep(1);
        }
    }
    
    //3.脱离进程空间
    shmdt(entry);
    
    //4.删除共享内存
    shmctl(shmid, IPC_RMID, 0);
    
    return 0;
}

client.cpp

#include "common.h"

#include <sys/shm.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <iostream>

int main()
{
    //定义共享内存结构图
    struct ShmEntry *entry;
    
    //1.申请共享内存
    int shmid = shmget((key_t)1111, sizeof(struct ShmEntry), 0666|IPC_CREAT);
    if(shmid == -1) {
        std::cout << "Create share memory error!" << std::endl;
        return -1;
    }
    
    //2.连接到当前进程空间/使用共享内存
    entry = (ShmEntry*)shmat(shmid, 0, 0);
    entry->can_read = 0;
    char buffer[TEXT_LEN];
    while(true){
        if (entry->can_read = 0) {
            std::cout << "Input message>>>";
            fgets(buffer, TEXT_LEN, stdin);
            strncpy(entry->msg, buffer, TEXT_LEN);
            std::cout << "Send message:" << entry->msg << std::endl;
            entry->can_read = 1;
        }
    }
    
    //3.脱离进程空间
    shmdt(entry);
    
    //4.删除共享内存
    shmctl(shmid, IPC_RMID, 0);
    
    return 0;
}

サーバーを実行する

クライアントを実行してメッセージを送信する

サーバーが情報を受信しました

上記のように、2つのプロセス間の通信はメモリを共有することによって実現されます。PHPの共有メモリに関連するAPIアドレス:https://www.php.net/manual/zh/ref.shmop.php

急速に変化するテクノロジーの常識を見つけることは、技術者のコアコンピタンスです。理論と実践を組み合わせた知識と行動の統一

おすすめ

転載: blog.csdn.net/self_realian/article/details/107225880