中島雄作@創価大学です。
次のプログラムはSolarisやSun OSで動作することが確かめられているプログ
ラムです。いま、そのプログラムを Linux へ移植しようとしているのですが
問題が発生しました。
まず、プログラムの説明をします。
これは共有メモリを使ったプロセス間通信をするプログラムです。
まず、shm_r.cのプログラムを起動させておき、それから、shm_s.cで
メッセージをキーボードで入力します。すると、共有メモリによるプロセス
間通信によりshm_r.c は shm_s.cからのメッセージを受け取って、その
メッセージの内容を表示するようになっています。
shm_r.c は、shm_s.c よりも先に実行されなければなりません。
さて、抱えている問題を紹介します。
shm_s.c のプログラムのなかでshmget()が使われている行に注目して下さい。
IPC_ALLOC という定数があります。
これは、Solaris, Sun OS では、既に共有メモリが存在していたら割り付けて、
共有メモリが存在していなければ失敗するという指定をすることができます。
しかしながら、IPC_ALLOCが、linuxのgcc-2.7.2では見当たらないのです。
/usr/include 以降の該当するヘッダファイルは確認したつもりです。
IPC_ALLOCはSolarisのみが採用しているものなのでしょうか?
最後に、このメールを呼んで下さった親切な方々へ
IPC_ALLOCに当たるもがLinux/gccにあればそれを、
直接的にIPC_ALLOCがなくても、間接的に同等の指定ができるのであれば
その方法を、
Linuxの共有メモリの扱いについて詳しく書いてある書籍もしくは URL
があればそれを
教えて下さい。
----------------------------------------------------------------------
Yusaku Nakajima
E-mail address : yn451132 _at_ edu.t.soka.ac.jp
URL : http://www.edu.t.soka.ac.jp/~yn451132
The best way to predict the future is to invent it.
----------------------------------------------------------------------
/*
shm_s.c
-- メッセージを共有メモリを通じて送る。
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h> /* 共有メモリを使うためには、 */
#include <sys/ipc.h> /* <sys/types.h>,<sys/ipc.h>,<sys/shm.h> */
#include <sys/shm.h> /* をインクルードする。 */
#include <signal.h>
#define SHMKEY 1994 /* 共有メモリを一意に識別するキー */
#define MAXMESLEN 1024 /* メッセージ長 */
#define MAXMESNUM 10 /* メッセージの数 */
typedef struct {
char flag; /* メッセージが入っているかどうかを示すフラグ */
char message[MAXMESLEN]; /* メッセージ */
} MES;
MES *maddr; /* 共有メモリをアタッチする仮想アドレスを入れるポインタ */
int shmid; /* 共有メモリ識別子 */
void main(void)
{
int i;
if((shmid = shmget(SHMKEY,MAXMESNUM*sizeof(MES),IPC_ALLOC|0666))<0){
perror("shmget");exit(EXIT_FAILURE); /* 共有メモリの割り当て */
}
maddr = (MES *)shmat(shmid,0,0); /* 共有メモリのアタッチ */
for(i=0; i < MAXMESNUM;i++)
if(!maddr[i].flag){
maddr[i].flag = -1; /* 領域のロック */
printf("send>");gets(maddr[i].message);
maddr[i].flag = 1; /* メッセージを共有メモリに書く */
shmdt((char *)maddr); /* 共有メモリのデタッチ */
exit(EXIT_SUCCESS);
}
printf("Message is full\n");
}
----------------------------------------------------------------------------
/*
shm_r.c
-- メッセージを他のプロセスから共有メモリを通じて受け取って表示する。
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h> /* 共有メモリを使うためには、 */
#include <sys/ipc.h> /* <sys/types.h>,<sys/ipc.h>,<sys/shm.h> */
#include <sys/shm.h> /* をインクルードする。 */
#include <signal.h>
#define SHMKEY 1994 /* 共有メモリを一意に識別するキー */
#define MAXMESLEN 1024 /* メッセージ長 */
#define MAXMESNUM 10 /* メッセージの数 */
#ifndef TRUE
#define TRUE 1
#endif
typedef struct {
char flag; /* メッセージが入っているかどうかを示すフラグ */
char message[MAXMESLEN]; /* メッセージ */
} MES;
MES *maddr; /* 共有メモリをアタッチする仮想アドレスを入れるポインタ */
void quit(int signal_number); /* シグナルハンドラ */
int shmid; /* 共有メモリ識別子 */
void main(void)
{
int i;
signal(SIGINT,quit); /* SIGINTを補足 */
if((shmid = shmget(SHMKEY, MAXMESNUM*sizeof(MES), IPC_CREAT|IPC_EXCL|0666)) < 0){
perror("shmget");exit(EXIT_FAILURE); /* 共有メモリの割り当て */
}
maddr = (MES *)shmat(shmid,0,0); /* 共有メモリのアタッチ */
for(i=0; i < MAXMESNUM; i++) maddr[i].flag = 0; /* フラグの初期化 */
while(TRUE) for(i=0; i < MAXMESNUM; i++)
if(maddr[i].flag == 1) { /* メッセージの表示 */
printf("received> %s\n",maddr[i].message); maddr[i].flag=0;
}
}
void quit(int signal_number)
{
switch(signal_number){
case SIGINT:
shmdt((char *)maddr); /* 共有メモリのデタッチ */
shmctl(shmid,IPC_RMID, 0); /* 共有メモリの削除 */
printf("共有メモリはデタッチかつ削除されました\n");
break;
}
exit(EXIT_SUCCESS);
}
----------------------------------------------------------------------
中島雄作 創価大学工学部情報システム学科青木ゼミ
Eメールアドレス: yn451132 _at_ edu.t.soka.ac.jp
ホームページ・ロケーション: http://www.edu.t.soka.ac.jp/~yn451132
未来は予想するより創ってしまう方が面白い(アラン・ケイ)