0

読む前に: バッファを初期化するために使用する calloc が問題の原因ですが、その理由はまだわかりません。バッファ配列を静的に定義すると、読み続けるとわかるように問題が修正されます...

受信スレッドと解析スレッドの 2 つのスレッドで構成される UDP サーバーを作成しています。受信スレッドは、recvfrom を使用してソケットをリッスンし、受信したメッセージを received_msgs_buf 配列にプッシュします。解析スレッドは、received_msgs_buf 配列からポップし、それをどうするかを決定します。

received_msgs_buf 配列はミューテックスによって保護されており、セマフォは解析メッセージ スレッドに信号を送って、配列からメッセージをポップしようとします。問題は、受信したメッセージを received_msgs_buf にプッシュしようとするたびに、segfault が発生することです。

バッファにメモリを割り当てる方法は次のとおりです。

// this is in the header file
extern UXIMessage::Wrapper* received_msgs_buf;

// this is in the main.cpp file that calls pthread_create()
UXIMessage::Wrapper* received_msgs_buf;

// This is in the init function for the receive thread, defined in the udp.cpp file
received_msgs_buf = (UXIMessage::Wrapper*)calloc(MAX_NUM_MSGS_IN_QUEUE, sizeof(UXIMessage::Wrapper));

受信スレッドで呼び出されるプッシュ関数は次のとおりです。

void push_to_receive_buf(UXIMessage::Wrapper uxi_msg) {
  pthread_mutex_lock(&received_msgs_mutex);
  if( num_received_msgs < MAX_NUM_MSGS_IN_QUEUE ) {
    printf("Message to put in buffer = %s\n", uxi_msg.DebugString().c_str());
    printf("Num received messages = %d\n", num_received_msgs);
    printf("Buf = %d\n", received_msgs_buf);
            // THE FOLLOWING LINE SEGFAULTS
    received_msgs_buf[num_received_msgs++] = uxi_msg;
  }
  pthread_mutex_unlock(&received_msgs_mutex);
  sem_post(&received_msgs_sem);
}

print ステートメントから、受信したメッセージの数が適切に 0 に初期化され、受信したメッセージが完全に有効であり、バッファー ポインターが NULL ではないことがわかります。印刷物は次のとおりです。

バッファに入れるメッセージ = message_id: OCU_HEARTBEAT ocu_heartbeat { ocu_id: 4747 }

受信メッセージ数 = 0

バフ = 778112

segfault は、= 演算子によって呼び出される CopyFrom() 関数で発生します。

編集: 遅くなりましたが、明日は C++ std::vector だけを使用してみます...

Edit2:明確にするために、ミューテックスとセマフォはすべて、次のようにメイン関数で適切に初期化されます。

pthread_mutex_init(&received_msgs_mutex);
pthread_mutex_init(&msgs_to_send_mutex);
sem_init(&received_msgs_sem, 0, 0);
sem_init(&msgs_to_send, 0, 0);

EDIT3:問題はCALLOCです。次のように received_msgs_buf を静的に定義すると、次のようになります。

 // this is in the header file
extern UXIMessage::Wrapper received_msgs_buf[MAX_NUM_MSGS_IN_BUF];

// this is in the main.cpp file that calls pthread_create()
UXIMessage::Wrapper received_msgs_buf[MAX_NUM_MSGS_IN_BUF];

コードは機能します... callocで私が間違っていることを誰か知っていますか?

4

2 に答える 2

0

まあ、質問がかなり古いものであっても、誰かが私のようにつまずくかもしれないので、私は 2 セントを差し上げます。単純な理由で安定して実行されます。これを理解するには数時間の調査が必要です。「共有」バッファーとバッファーカウンターを並列アクセスから保護しても、1 つのスレッドが認識しないという問題がまだあります。別のスレッドが何かを変更しました。そのため、(ソフトウェア アルゴリズムとハードウェアによって) メモリ コンテンツをキャッシュし、もはや真実ではないものを認識します。「揮発性」(ハードウェアレジスタなどの読み取りを目的としている)を誤用していくつかの問題を修正しても、

「メモリバリア」について読み、それらを理解すると、(新しい) コードがおそらく機能するようになります。

于 2015-04-30T19:05:45.427 に答える