进程间同步(Process Synchronization)-2 通过semaphore方式来实现进程间同步的例子

 

出处:仮想デバイスドライバを利用したプロセス間通信について http://cheesy.dip.jp/tutorialog/archives/6

仮想デバイスドライバを利用したプロセス間通信について説明します。といってもよくわからないと思うので、ちゃんと説明します。
Unixでプロセス間通信というと、ソケットを使ったもの、パイプを使ったもの、共有メモリを使ったもの等がありますが、それぞれ長所・短所があると思います。
ものすごく簡単に言うと、
ソケットでは、

  • 複数マシン間での通信が可能
  • 通信処理のオーバーヘッドが大きい(コネクション開始・終了処理も含め)
  • パイプでは、

  • ソケットより通信処理のオーバーヘッドが少ない
  • 親子関係のプロセスに限定される
  • 共有メモリでは、

  • シンプルで高速
  • 書き込み・読み取りの同期をとるのが難しい
  • 等が挙げられると思います。


    共有メモリがシンプルかつ高速ですばらしいのですが、アプリケーションレベルで同期をとるのが難しいという問題があります。そこで、ここでは、

    共有メモリによるプロセス間通信における同期機構を、仮想デバイスドライバを使って行う手法を説明しようと思います。

    開発環境は、FedoraCore4(2.6.11-1.1369_FC4)、gcc 4.0.0、GNU make 3.80です。

    Linuxのデバイスドライバについては、私も詳しくないですが、以下のページが参考になると思いますので、書いたことのない方は一度見てみてください。

    The Linux Kernel Module Programming Guide
    Linux Kernel Module programming(Kernel 2.4)

    概要

    同期の仕組みですが、デバイスドライバにpoll関数を実装し、そこで読み込みと書き込みの待ち列を設定します。書き込み(write)後に読み込み可能

    になったら読み込みの待ち列に対して、wake_upを実行します。ユーザ側のプロセスでは、デバイスドライバをselect(2)で待ち(poll関数が呼び出

    される)、読み込み可能になり次第、カーネルから起こされ読み込み処理を実行できるようになります。 書き込みも同じ原理で動きます。しかし、読み込

    みと書き込みは同時には実行できません。(当たり前ですが。)

    実装

    次に、実際のソースについて解説します。デバイスドライバといっても、本物のデバイスを操作するわけではなく、同期を取るだけで実際の通信データも

    扱わないので非常に単純です。ソースはこちらです。(sync.c)

     

    コンパイル

     

    ソースのコンパイルは以下のMakefileを使います

    % make
    make -C /lib/modules/2.6.11-1.1369_FC4/build M=`pwd` V=1 modules
    ...

    モジュールをカーネルに組み込む

    コンパイルがうまくいくと、モジュールファイルsynk.koができていると思います。後は組み込んで、デバイスファイルを作るだけです。

     

    % sudo /sbin/insmod sync.ko
    % sudo mknod /dev/sync c 100 0
    以上で、プロセス間同期用のデバイスファイルの作成と組み込みは終わりです。	

    動作テスト

    次は実際に、書き込み、読み込みの2プロセス間でプロセス間通信をさせてみます。
    まずは書き込みのプログラムです。(map_write.c)

    次に読み込み側です。(map_read.c)

    コンパイルし、実際に動かしてみます。

     

    % gcc map_write.c -o map_write
    % gcc map_read.c -o map_read
    読み込みプロセスを実行すると、書き込みがあるまで待ちます。
    % ./map_read
    selecting ...
    書き込みを実行すると、書き込み可能なため待つことなく、書き込みを実行し、その直後に
    読み込み可能となり、共有メモリからのデータを受け取ることができます。
    % sudo ./map_write
    selecting ...
    wait released.
    % ./map_read
    selecting ...
    get data from mapped area [Hello, are you getting my request ?]
    まとめ

    今回は、共有メモリにおけるプロセス間通信の欠点を補うような同期機構を、仮想デバイスファイルを利用することによって実現しました。

    この機構を利用すれば、同一マシン間での高速なプロセス間のデータ受け渡しが可能になるので、パフォーマンスが重要になってくるよう

    なアプリケーションで役に立つかもしれません。

    知识点补充

    sem_init - initialise an unnamed semaphore

    Synopsis

    #include <semaphore.h>
    int sem_init(sem_t *sem, int pshared, unsigned int value);

    Description

    sem_init() initialises the unnamed semaphore at the address pointed to by sem
    The value argument specifies the initial value for the semaphore.The pshared argument 
    indicates whether this semaphore is to be shared between the threads of a process, 
    or between processes.

     

     

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值