2016-08-16 2 views
0

私は現在shmgetとshmatを使って2つのプロセス間で共有メモリを作成しています。プロセスが終了すると、共有メモリはまだ生き残っており、プロセスを再起動すると、以前の場所から開始することができます。しかし、マシンをオフにしてからオンにすると、データが失われています。再起動時に共有メモリのデータを保持していますか?

私はshmget/shmatや他の方法でプロセス間で共有メモリを作るオプションがあるかどうか知りたいのですが、再起動してもデータを生かしておくことができます。

今、私はこの種のものやっている:

const char *ZoneFile = "/home/Zone.dat";' 
key_t sharedKeyZone; 
int sharedSpaceIdZone; 

int descriptor = open(ZoneFile, O_CREAT | O_RDWR, S_IRWXU); 
close(descriptor); 
sharedKeyZone = ftok(ZoneFile, 1); 
sharedSpaceIdZone = shmget(sharedKeyZone, 1 * sizeof(Zone_t), IPC_CREAT); 
ZoneArray = (Zone_t *) shmat(sharedSpaceIdZone, NULL, 0); 

Zone_tは、構造体の型であることを、私は問題なく私の2つの工程から[0] ZoneArray内のすべてのデータにアクセスすることができます。

私は考えることができる唯一の解決策は、システムの状態を "保存"するために定期的にデータを書き込むことです。再起動するとこのファイルが読み込まれますが、構造は後で進化しなければならない。

編集:私はMSYNCこの方法でMMAPを使用しようとした@Wumpus Q. Wumbleyのアイデア次たshmgetとにshmatと同様

#include <stdio.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <semaphore.h> 

//add rt to eclipse librairies 

typedef struct count { 

    int counter; 
} count; 

int main() 
{ 
    count *memory; 
    int fd = shm_open("MYmemory.txt", O_CREAT | O_RDWR, S_IRWXU); 

    if(fd == -1) 
    { 
     perror("shm_open"); 
     return 1; 
    } 

    ftruncate(fd, sizeof(count)); 
    memory = mmap(NULL, sizeof(count), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    printf("before %d\n", memory->counter); 
    memory->counter = 5; 
    printf("after %d\n", memory->counter); 
    if(msync(memory, sizeof(count),MS_SYNC)<0) 
    { 
     printf("%s","msync ERROR."); 
    } 
    else { printf("%s","msync completed successfully.");} 

    return 0; 
} 

同じ結果を、再起動後にデータが(0です。ショー0) "前" のprintf

EDIT 2:

これは私のためにそれをやった:

count *memory; 
    int fd = open(MYmemoryFile, O_CREAT | O_RDWR, S_IRWXU); 

    ftruncate(fd, sizeof(count)); 
    memory = mmap(NULL, sizeof(count), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    printf("before %d\n", memory->counter); 
    memory->counter = 5; 
    printf("after %d\n", memory->counter); 
    if(msync(memory, sizeof(count),MS_SYNC)<0) 
    { 
     printf("%s","msync ERROR."); 
    } 
    else { printf("%s","msync completed successfully.\n");} 

私の前のコードではどこからでも完璧ではありませんでしたが、ポインタフォームなしでメモリを使用していました(Zone [0] .paramは現在Zone [0] - > paramです)。これは@Wumpus Qのおかげです。 Wumbley。

EDIT 3:誰かが後でそれについて検索する場合は、ここで私は構造で動作するようにそれを固定する方法である:

#include <stdio.h> 
#include <sys/mman.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <unistd.h> 
#include <semaphore.h> 

//add rt to eclipse librairies 


const char *MYmemoryFile = "/home/memorystruct.txt"; 


typedef struct count 
{ 
    int counter; 
    int test; 
} match[5]; 

int main() 
{ 

    int fd = open(MYmemoryFile, O_CREAT | O_RDWR, S_IRWXU); 

    ftruncate(fd, sizeof(match)); 
    struct count *memory = mmap(NULL, sizeof(match), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 
    printf("before memory[0].counter %d\n", memory[0].counter); 
    printf("before memory[0].counter %d\n", memory[0].test); 
    printf("before memory[1].counter %d\n", memory[1].counter); 
    memory[0].counter = 5; 
    memory[0].test = 2; 
    memory[1].counter = 17; 
    printf("after memory[0].counter %d\n", memory[5].counter); 
    printf("after memory[1].counter %d\n", memory[1].counter); 
    if(msync(memory, sizeof(match),MS_SYNC)<0) 
    { 
     printf("%s","msync ERROR."); 
    } 
    else 
    { 
     printf("%s","msync completed successfully.\n"); 
    } 

    return 0; 
} 
+1

ミッションクリティカルなデータの場合は、外部キューを使用しないでください。 – Leon

+0

私はコメントを理解していないが、キューの持続性ではなく、メモリへのアクセス権の順序を規制しないと申し訳ありません。 – Wowy

+0

私が知る限り、 'shm_open'は再起動後に消える一時ディレクトリにファイルを作成します。したがって、ディレクトリを選択し、通常のオープンでファイルを作成し、必要な長さにftruncateしてmmapします。 "shm"で始まる名前の関数は実際には必要ありません。 –

答えて

5

あなたmmapMAP_SHAREDと通常のファイルは、あなたが効果的にもSHMセグメントを持っている場合永久的なファイル。ディスク上のコピーはメモリ内のコピーの後ろに位置しますが、msyncと呼ぶと定期的にフラッシュできます。

+0

ニース。ただし、共有メモリの更新がディスクに部分的にしか保存されないという問題があります。クリーンなシャットダウンで何らかのフラッシュが必要になるかもしれません。 –

+0

これについて少し調べて、このような小さなコードをしようとしました(編集を参照) – Wowy

関連する問題