2013-08-06 3 views
1

고성능 C++ 항목이 필요하므로 가능할 때마다 데이터를 복사하지 않아야합니다.복사하지 않고 문자열을 zmq :: message_t에 할당하십시오.

따라서 문자열 버퍼를 복사하지 않고 zmq :: message_t 객체에 직접 할당하려고합니다. 그러나 성공적인 전송을 피하는 문자열의 일부 할당 해제가있는 것으로 보입니다. 여기

코드의 조각 :

for (pair<int, string> msg : l) { 
    comm_out.send_int(msg.first); 
    comm_out.send_int(t_id); 

    int size = msg.second.size(); 
    zmq::message_t m((void *) std::move(msg.second).data(), size, NULL, NULL); 
    comm_out.send_frame_msg(m, false); // some zmq-wrapper class 
} 

어떻게 메시지가 발송되기 전에 문자열이 해제되는 것을 방지 할 수 있습니다? 문자열이 정확히 할당 해제 된 시점은 언제입니까?

안부

답변

1

나는 zmq::message_t m((void *) std::move(msg.second).data()... 아마 정의되지 않은 동작이지만, 확실히 문제의 원인이라고 생각합니다. 이 경우에 std::move은 내가 생각하는 것처럼 보이지 않습니다.

std::move을 호출하면 msg.second의 내용을 이동 한 다음 해당 임시 데이터에 대한 포인터를 message_t 생성자에 전달하여 익명의 임시 문자열을 효과적으로 생성 할 수 있습니다. 0MQ 코드는 포인터가 이 유효하고이라고 가정하지만 을 호출하기 전에 즉, message_t의 생성자가 완료되면 임시 개체가 삭제됩니다.

제로 카피는 자세한 내용은 0mq (the 0MQ Guide 참조)의 복잡한 문제이지만, 0MQ가 완료되었다는 것을 명시 할 때까지 복사되지 않은 데이터가 유효한지 확인해야합니다.

이 상황에서 C++ 문자열을 사용하는 경우 이고 많은 생각이 필요합니다. "문자열이 할당 취소되는 것을 피하는 방법"에 대한 질문은 문제의 핵심으로 바로 넘어갑니다. 그것에 대한 유일한 대답은 "아주 조심스럽게"입니다.

요컨대, 제로 카피가 필요합니까?

+0

친애하는 SteveL에게 고성능 복사를 위해 항상 제로가 더 좋습니다. 사본을 피할 수 있다면이를 수행해야합니다. 그렇게 생각하지 않아? 총 33MB는 복사해야합니다. 두 번째 방법은 zmq.hpp 문자열을 &&를 사용하고 클래스 구성원 문자열에 해당 문자열을 적용하는 다른 생성자로 확장하는 것입니다. 이 아이디어에 대해 어떻게 생각하십니까? 감사합니다. – moo

+0

@ user2237976 - 제로 복사는 코드를 올바르게 쓰고 읽기가 어렵게 만들 수 있으므로 항상 그렇게하는 것이 반드시 올바른 것은 아닙니다. 'zmq.hpp' 코드를 변경하는 것을 권장하지 않습니다. 업그레이드를 원할 때 유지 관리 문제가 될 수 있습니다. 아마도 당신은 자신의 추상화에서'zmqcpp'를 래핑 할 수도 있고, 필요로하는 변경으로 원래의 0MQ C 라이브러리를 감쌀 수도 있습니다. – SteveLove

+0

이 코드는 연구 대상 일 뿐이므로 모든 라이브러리에서 매우 읽기 쉽거나 호환 가능할 필요는 없습니다. 내 접근 방식이 작동하는지 여기에서 확인하고 알려 드리겠습니다. – moo

관련 문제