2010-12-20 14 views
2

私はプロセス間の障壁のための簡単な解決策が必要でした。ここで解決策:solutionプロセス間の共有メモリとpthread_barrier:どのように安全ですか?

しかし、私は完全にmmapで失われています...私の最初の試行では、10回中1回失敗します(セグメンテーションまたはデッドロック)。

私は自分の問題が同期の問題であると理解していますが、見つけられません。私はmmapedメモリ(example)を設定するための例を見つけましたが、mmaped pthread_barrierには良いとは思いません。ここで

私のコードの抜粋:

#define MMAP_FILE "/tmp/mmapped_bigdft.bin" 

void init_barrier() { 
    pthread_barrier_t *shared_mem_barrier; 
    pthread_barrierattr_t barattr; 
    pthread_barrierattr_setpshared(&barattr, PTHREAD_PROCESS_SHARED); 

    hbcast_fd = open(MMAP_FILE, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); 
    result = lseek(hbcast_fd, sizeof(pthread_barrier_t)-1, SEEK_SET); 
    result = write(hbcast_fd, "", 1); 
    shared_mem_barrier = (pthread_barrier_t*) mmap(0, sizeof(pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, hbcast_fd, 0); 
    if (mpi_rank == 0) { 
    int err = pthread_barrier_init(shared_mem_barrier, &barattr, host_size); 
    } 
    MPI_Barrier(some_communicator); 
} 

質問:

  • 私はmmapの初期化中に何かを欠場か?
  • どの操作をすべてのプロセスで実行する必要がありますか? pthreadの障壁を管理するためのSAFIERある

新しい問題

?あるいは、彼らは同じメカニズムに基づいていますか?

  • たshmget
  • 場合、shm_open
  • のmmap
  • 別の1

答えて

1

あなたはすべてのプロセスのためにO_TRUNCでファイルを開くにはしたくありません。これを行うたびに、ファイルをもう一度切り捨てて、実行していた以前のmmap操作を無効にする可能性があります(以前のmmapのファイルサイズ変更時の影響は一般的には未定義です)。

mmap'dのメモリにセマフォーを持っていて、それが正しく機能するとは思えません。(これはOSのプラットフォームによってはうまく機能しないかもしれません。

本当に使いたいのは共有メモリです。 manを "shmget"と "shmat"で実行して、共有メモリを作成してマップする方法を学んでください。あなたはおそらく共有メモリIDを渡すためにファイルを必要とするでしょうし、シグナルハンドラを登録することによってアプリケーションクラッシュ時に共有メモリIDを解放することに注意する必要があります。それ以外の場合は、ゾンビの共有メモリ割り当てをそのままにしておき、OSリソースの制限をオーバーランさせることができます。マスタースレッドで共有メモリセグメントを作成しようとしたときにENOSPCを取得した場合は、そのことが分かります。

+1

すべてのことを説明するポインタがありますか?あなたは、mmapはpthread_barrierには最適ではないと言いました。 shmgetは良いですか?別に覚えていますか? –

2

チャールズが言及したように、切り詰めがあなたに届いているように見えます。また、pthread_barrierattr_initを使用して属性を初期化する必要があります。

他の質問については、ただ1つのプロセスで初期化を行う必要があり、すべてのプロセスでpthread_barrier_wait(MPIと同様)を呼び出す必要があります。

私はあなたの他の質問を見ました。だから私はあなたがMPIを使いたくない理由を知っています。

if (rank == 0) 
{ 
    /* Create the shared memory segment, initialise the barrier. */ 
} 
MPI_Barrier(communicator); 
if (rank != 0) 
{ 
    /* Load the shared memory segment, cast it to a pthread_barrier_t* and store. 
    * It's already initialised */ 
} 
+0

どの共有メモリメソッドを使用しますか? –

+0

私がプロセス間の障壁を必要とした最後の時に、私はMPIを使いました;)あなたがすでに使っているPOSIX共有メモリはうまくいくはずです。共有メモリーが正しく初期化される前に、他のプロセスが共有メモリーにアクセスするのを止めるだけで済みます。 – axw

+0

私の質問は、共有メモリのパラダイムをpthread_barrierに使うべきかどうかということでした:mmap、shmget、もう一つ? –

1

あなたが共有セグメントを作成するためにshm_openを使用する必要があります。だから、おそらくそうのように、あなたのpthreadの障壁を初期化するために1つだけMPIバリアにしてください。 paramenter O_CREATあなた で

  • は、プロセス は、セグメントを作成する最初のものであるかどうかを検出することができるはずです。
  • このプロセスだけが セグメントを適切な長さにトランケートし、 にマップしてバリアを初期化する必要があります。
  • が最初ではないことを検出する他のすべては、 のためにスリープ状態になりますが、秒間で十分である必要があります。次にセグメントをマップします。
  • その後、すべてのプロセスがバリアを同期させることがあります。
関連する問題