読む前に: バッファを初期化するために使用する 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で私が間違っていることを誰か知っていますか?