同じPC内に複数の共有メモリを作ろうとしています。自分の考えでは共有メモリを作成するときに
shmget(key_t key, int size, int shmflg)
のkeyを変えれば複数の共有メモリを作れると思ったのですがうまくいきません。ちなみにkeyは
key = ftok(const char *pathname, int proj_id);
で取得していて、pathnameとproj_idを変えればkey_tの値も変わり、複数の共有メモリが確保できると思ったのですが・・・。
また、ipcsで確認したところできた共有メモリのキーが0xffffffffになっているのも気になりました。普通は0x00000000になるべきなんでしょうか?
No.1
- 回答日時:
OSは?
うまくいかないとは、どういう状態か? 詳しく具体的に。
考え方自体はあっているように思えますので、実際のコードに何か問題があるように思えます。
また、shmgetだけでは共有メモリ・セグメントの識別子を返すだけですから、これだけでは使用可能な共有メモリができていないことは分ってますよね?
この回答への補足
OSはRedhatlinux8です。ソースは以下のような感じです。shm.cで初期化、アクセス、消去の関数を作って
cc -o main main.c shm.c
でコンパイルして使っています。
複数作るときはftokの引数を変えているだけなんですがこれではだめなのでしょうか?実際に実行すると一つ目はうまくいくのですが二つ目になると
Can't Access to the shared memory
と出てしまいます。
-----SHM.h----------------
#ifndef __SHM_H__
#define __SHM_H__
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/msg.h>
#define SHM PARAM KEY 0x1000
#define KEYFILE_PATH "host"
#define PROJ_CHAR (char) 'dbhost'
#define FIN (255)
struct SHM_PARAM{
int shd_param_id;
int status;
int a;
int b;
int c;
};
#endif /* __SHM_H__ */
extern int shm_initialize(key_t shm_key, int shm_size, int *shrd_id, int *shm_ptr);
extern int shm_access(key_t shm_key, int shm_size, int *shrd_id, int *shm_ptr);
extern int erase_shm(struct SHM_PARAM *pram_ptr);
-------SHM.c------
#include "shm.h"
int shm_initialize(
key_t shm_key, /*共有メモりの為のキーワード*/
int shm_size, /*共有メモりのサイズ*/
int *shrd_id, /*共有メモりIDへのポインタ*/
int *shm_ptr) /*共有メモりの先頭アドレスへのポインタ*/
{
/*現状態へのアクセス*/
*shrd_id = shmget(shm_key, shm_size, IPC_CREAT|0666);
if(*shrd_id < 0){
printf("[shm_initialize]:Can't Access to the shared memory!!\n");
return -1;
}
*shm_ptr = (int)shmat( *shrd_id, NULL, 0);
memset((void*)*shm_ptr, 0, shm_size);
/*終了*/
return ( *shrd_id);
}
int shm_access(
key_t shm_key,
int shm_size,
int *shrd_id,
int *shm_ptr)
{
*shrd_id = shmget(shm_key, shm_size, 0444);
if( *shrd_id < 0){
printf("Can't Access to the shared memory!!\n");
return (-1);
}
*shm_ptr = (int)shmat( *shrd_id,(const void*)NULL, 0);
return ( *shrd_id);
}
int erase_shm(struct SHM_PARAM *param_ptr)
{
shmctl(param_ptr->shd_param_id, IPC_RMID, 0);
return (0);
}
---main.c---
#include "shm.h"
int shd_param_id; /*共有メモりのID*/
struct SHM_PARAM *param_ptr; /*共有パラメータへのポインタ*/
key_t key;
int main(int argc, char **argv)
{
int i;
key = ftok(KEYFILE_PATH, PROJ_CHAR);
shm_initialize(key,
sizeof(struct SHM_PARAM),
&shd_param_id,
(int *)¶m_ptr);
param_ptr->shd_param_id = shd_param_id;
printf("Memory attaced at %x \n", (int)param_ptr);
printf("a=%d\n",param_ptr->a);
printf("b=%d\n",param_ptr->b);
printf("c=%d\n",param_ptr->c);
//erase_shm(param_ptr); //
param_ptr->status = FIN;
return 0;
}
No.2
- 回答日時:
>複数作るときはftokの引数を変えているだけなんですがこれではだめなのでしょうか?
具体的に何を指定したか書いてください。
>実際に実行すると一つ目はうまくいくのですが二つ目になると
Can't Access to the shared memory
と出てしまいます。
具体的にどうやっていますか。
単一プログラム中で shm_initialize()を複数呼び出している、別プログラムでパラメタを変えて複数起動している、同一のプログラムを二つ起動している等。
使い方を誤解されているのかも。
ざっと見たところ
key = ftok(KEYFILE_PATH, PROJ_CHAR);
ですが、多分
key_t ftok(const char *pathname, int proj_id);
なのに、
#define PROJ_CHAR (char) 'dbhost'
が気になります。
この回答への補足
返信遅れてしまってすみません。
えっと使い方なんですが前に載せたプログラム(shm.h shm.c main.c)を違うディレクトリにおいてftokの引数であるpathnameとproj_idだけを変えて使おうとしています。(つまりpathnameとproj_idの部分だけが違うプログラムを違うディレクトリにおいて複数の共有メモリを作ろうとしています)
>ざっと見たところ
key = ftok(KEYFILE_PATH, PROJ_CHAR);
ですが、多分
key_t ftok(const char *pathname, int proj_id);
なのに、
#define PROJ_CHAR (char) 'dbhost'
が気になります。
確かに・・。ここはint型にしたほうがいいですよね。
でもint型にしても出来ませんでした・・・。
それで今、ftokを使わずにkeyを無理やり自分で設定したら複数できました・・・。(key = 1とか無理やりkeyを決める)
でもこれってまずいですよね?
No.3
- 回答日時:
現状はftok()が失敗して-1を返してきていると思われます。
毎回key=-1でshmget()していれば同じ結果になるのは当然ですよね。
まずはkeyの値を確認してみてください。
その後、#2さんが気にされている箇所を修正してみては如何でしょうか。
# int型に渡すので文字列は間違いということは分かりますよね?
# 定義をじっくり見てください。文字列が''で囲まれています。だからといって
# 早まって""に直さないでください。
# 要は'a'みたいに文字を定義してください。
この回答への補足
えと結果から言うと全然うまくいきませんでした。
まず今まで指摘されたことを直しました。
いままではエラーのときの対応をしていなかったのでkeyの指定のところにエラーの対応を入れました。
key = ftok(KEYFILE_PATH, PROJ_CHAR)
if(key == -1){
perror("ftok()");
return 1;
}
それでまず第二引数をint型に直したところ
(#define PROJ_CHAR 7としました)
問題なくコンパイルが通ったのでいけるかなと思い実行してみると
ftok():No such file or directory
このエラーはどういうエラーなのでしょうか?
またこの状態でpareoraraさんが指摘されていた文字列指定のところを直したところ
("host"のところを'host'に変更)
警告:複数文字からなる文字定数
警告:引数1個の'ftok'を渡しますにより、キャストなしで整数からポインタを作りました
とでて、実行したところ
ftok():Bad address
と出てしまいました。ここでいう整数からポインタを作るとはどういう意味なのでしょうか?
また、自分で色々調べたところftokには
int ftok ( string pathname, string proj )
という引数指定があるようなのですがこれは
key_t ftok(const char *pathname, int proj_id);
とは全く別のものなのでしょうか?
多々質問してしまって申し訳ありません。ご指導お願いします。
No.4ベストアンサー
- 回答日時:
#3です。
> ftok():No such file or directory
「ファイルかディレクトリがない」というメッセージです。
ftok()でこのメッセージに関係するところといったらファイル名が思いつきませんか?
> ("host"のところを'host'に変更)
いえいえ違います!
' 'で文字列を指定していることが間違っているという指摘です。
proj_idはint型なので文字列"abc"でなく、文字'a'としないと駄目ということです。
" "と' 'で囲む意味と違いを考えてください。
# × int a = "abc";
# × int a = 'abc';
# ○ int a = 'a';
もちろん、int型なので
> (#define PROJ_CHAR 7としました)
は、間違いではありません。
>int ftok ( string pathname, string proj )
プラットフォームによる違いです。第二引数がchar型という環境もあります。
で、いろいろと思考錯誤が入ったと思いますが、質問当初に頭をリセットしてください。
key = ftok(KEYFILE_PATH, PROJ_CHAR);
がどうなれば良いかというと
key = ftok("host", 'a');
の形になれば良いです。
これで「ftok():No such file or directory」のエラーが出るようであれば、ファイルの置かれている場所へのパスが通ってないということなので、ファイルを見つけられるようにパス指定を変えれば良いだけです。
実行形式mainと同じ場所にhostファイルがあるなら、"./host"とするとか、フルパス指定にするとかです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL エラー 1068 (42000): 複数の主キーが定義されていますエラー 2 2022/11/17 04:36
- CPU・メモリ・マザーボード USB Key 2 2022/07/06 14:25
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
- CPU・メモリ・マザーボード ノートパソコンでクロック数の違うメモリを1枚ずつ挿してデュアルチャンネルになりますか? 1 2022/11/18 00:30
- ノートパソコン celeronはまだゴミですか? 8 2022/11/19 13:41
- MySQL MYSQL エラー 2 2022/10/18 11:37
- その他(パソコン・周辺機器) 2つのPCを行き来する 2 2022/06/15 01:59
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
- CPU・メモリ・マザーボード AUSU PRIME X570-PROというマザーボードを使用しており、タルコフというゲームを快適に 2 2022/12/31 15:38
- その他(自然科学) 論文のまとめに関して(小論文)添削お願いします。 6 2023/07/16 14:24
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
2の補数を計算するプログラム
-
intとlongは同じ?
-
再起呼び出しの回数をカウント...
-
C言語で%を使わない余りの出し方
-
迷路を脱出する経路探索プログ...
-
画像の拡大・縮小
-
分数の足し算をさせるプログラ...
-
C言語で簡単なパックマンゲーム...
-
C++で表を作成したいのです ...
-
条件が多い場合
-
複数の共有メモリの作成
-
ヒストグラム均等化処理プログラム
-
3のつく数と3の倍数を表示 C言語
-
argvのNULLチェック
-
乱数で交互に偶数、奇数が、、、。
-
プログラミングに関して
-
OpenCVによる4値化について
-
再帰処理をループ処理に変換
-
16bitで乱数を生成する方法
-
C++ Debug Errorについて教えて
おすすめ情報