4

を使用して、共有メモリ IPC をテストするために、マスターとスレーブの 2 つのプロセスを作成しました。マスターは共有メモリを作成して書き込みを開始し、しばらくしてスレーブが接続すると、これは機能しますが、一度スレーブが接続すると、マスターが共有メモリに書き込むすべてのデータを受信/取得しません。

マスターコードは次のようになります。

    typedef struct custom_data_s {
      整数分;
      整数最大;
      /* 共有対象 */
      pthread_mutex_t ipc_mutex;
      pthread_cond_t ipc_condvar;
    } custom_data_t;

    int main(void) {
      int fd = -1;
      custom_data_t *this_custom_data;
      pthread_mutexattr_t mutex_attr;
      pthread_condattr_t cond_attr;

      fd = shm_open("/A_CUSTOM_DATA", O_RDWR | O_CREAT | O_EXCL , (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
      if(fd == -1) {
        printf("エラー fd %d %s\n",fd,strerror(errno));
      }

     if (ftruncate (fd,sizeof(custom_data_t)) == -1) {
        printf("ERROR tricate fd %d %s\n",fd,strerror(errno));
        出口 (1);
      }

      this_custom_data = (custom_data_t *) mmap(NULL, sizeof(custom_data_t), PROT_READ | PROT_WRITE , MAP_SHARED ,fd ,0);
      if(this_custom_data ==(custom_data_t *) -1) {
        printf("エラー マッピング fd %d %s\n",fd,strerror(errno));
        出口 (1);
      }
      閉じる (fd);

      pthread_mutexattr_init(&mutex_attr);
      pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
      pthread_mutex_init(&this_custom_data->ipc_mutex, &mutex_attr);

      pthread_condattr_init(&cond_attr);
      pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
      pthread_cond_init(&this_custom_data->ipc_condvar, &cond_attr);

     for (fd=0; fd != 100000; fd++) {
        pthread_mutex_lock(&this_custom_data->ipc_mutex);
        this_custom_data->min = fd;
        this_custom_data->max = fd+5;
        pthread_cond_signal(&this_custom_data->ipc_condvar);
        pthread_mutex_unlock(&this_custom_data->ipc_mutex);
      }
      /* クリーンアップと終了は、すべての終了コードをチェックする必要があります*/
      pthread_mutexattr_destroy(&mutex_attr);
      pthread_condattr_destroy(&cond_attr);

      pthread_cond_destroy(&this_custom_data->ipc_condvar);
      pthread_mutex_destroy(&this_custom_data->ipc_mutex);

      if(0 != munmap(this_custom_data, sizeof(custom_data_t))) {
        printf("%s のアンマッピング エラー\n",strerror(errno));
        出口 (1);
      }  
      if (0 != shm_unlink("/A_CUSTOM_DATA")){
        printf("%s のリンク解除エラー\n",strerror(errno));
        出口 (1);
      }
      0 を返します。
    }

たとえば、マスターは、スレーブが接続されると、しばらくしてから共有メモリに最小値と最大値を 1 から 10000 に書き込み始めます。スレーブが接続すると、マスターによって書き込まれたすべてのデータを読み取る必要があります。私は間違っていますか?スレーブが設定する別の条件変数が必要ですか? 共有メモリを学習しようとしていますが、何か間違っているか、ミューテックスと共有メモリの仕組みを理解していないと思います。スレーブでは、条件変数が設定されるのを待っています。ここにスレーブのコードがあります。

    typedef struct custom_data_s {
      整数分;
      整数最大;
      /* 共有対象 */
      pthread_mutex_t ipc_mutex;
      pthread_cond_t ipc_condvar;
    } custom_data_t;

    int main(void) {
      int fd = -1;
      custom_data_t *this_custom_data_ptr;
      custom_data_t this_data;
      int prv_packet = 0;

      fd = shm_open("/A_CUSTOM_DATA", O_RDWR , (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH));
      if(fd == -1) {
        printf("エラー fd %d %s\n",fd,strerror(errno));
      }

      if (ftruncate (fd,sizeof(custom_data_t)) == -1) {
        printf("ERROR tricate fd %d %s\n",fd,strerror(errno));
        出口 (1);
      }

      this_custom_data_ptr = (custom_data_t *) mmap(NULL, sizeof(custom_data_t), PROT_READ | PROT_WRITE , MAP_SHARED ,fd ,0);
      if(this_custom_data_ptr ==(custom_data_t *) -1) {
        printf("エラー マッピング fd %d %s\n",fd,strerror(errno));
        出口 (1);
      }
      閉じる (fd);
    ながら (1) {
        pthread_mutex_lock(&this_custom_data_ptr->ipc_mutex);
        pthread_cond_wait(&this_custom_data_ptr->ipc_condvar, &this_custom_data_ptr->ipc_mutex);
        memcpy(&this_data, this_custom_data_ptr, sizeof(this_custom_data_ptr));
        もし (prv_packet == 0) {
          printf ("最初に取得");
          prv_packet = this_data.min;
        }
        if ((prv_packet +1) != this_data.min){
          printf ("エラー prv:%d this:%d\n", prv_packet, this_data.min);
        }
        pthread_mutex_unlock(&this_custom_data_ptr->ipc_mutex);
        prv_packet = this_data.min;
      }
      0 を返します。
    }

私は何を間違っていますか?スレーブが接続されるとデータが失われないように同期する方法はありますが、接続されていない場合はマスターもブロックされません。

4

0 に答える 0