Study/에러 정리
람다식 캡쳐와 const, 공유포인터 업데이트 문제
Juzdalua
2024. 9. 8. 01:58
작업중인 스레드 내부에서 다른 스레드에게 비동기 작업을 요청하는 과정에서 문제가 발생했다.
정확히는 공유포인터를 매개변수로 람다식 내부에서 사용할 때 문제가 발생했다.
처음에는 참조캡쳐(&)로 메모리를 아껴야겠다는 생각을 했다.
주소값을 건네 받고 스레드가 작업을 시작하면 미리 선언된 공유포인터의 메모리는 해제되고 공유포인터의 주소값은 null값을 가르키게 되었다.
// Room.h
void UpdateRoomItem(shared_ptr<RoomItem>& roomItem);
// Room.cpp
void Room::UpdateRoomItem(shared_ptr<RoomItem>& roomItem)
{
업데이트 로직
}
shared_ptr<RoomItem> roomItem = ItemController::GetRoomItemByRoomItemId(recvItem.roomitemid());
thread([&]() {
this_thread::sleep_for(3s);
...
GRoom.UpdateRoomItem(roomItem); // Error
...
GRoom.Broadcast(MakeSendBuffer(createRoomPkt, createRoomPacketId));
}).detach();
그래서 소유권을 아예 넘기면 되지 않을까 시도해봤지만 동일한 에러가 발생했다.
shared_ptr<RoomItem> roomItem = ItemController::GetRoomItemByRoomItemId(recvItem.roomitemid());
thread([&, std::move(roomItem)]() {
this_thread::sleep_for(3s);
...
GRoom.UpdateRoomItem(roomItem); // Error
...
GRoom.Broadcast(MakeSendBuffer(createRoomPkt, createRoomPacketId));
}).detach();
수정된 코드
공유포인터를 복사하면 useCount가 증가하여 레퍼런스참조가 되는 것을 미처 생각하지 못했다.
그리고 실질적으로 업데이트 되지 않는 공유포인터는 const 상수 매개변수로 넘겨주었다.
// Room.h
void UpdateRoomItem(const shared_ptr<RoomItem>& roomItem);
// Room.cpp
void Room::UpdateRoomItem(const shared_ptr<RoomItem>& roomItem)
{
업데이트 로직
}
shared_ptr<RoomItem> roomItem = ItemController::GetRoomItemByRoomItemId(recvItem.roomitemid());
thread([=]() {
this_thread::sleep_for(3s);
...
GRoom.UpdateRoomItem(roomItem); // Error
...
GRoom.Broadcast(MakeSendBuffer(createRoomPkt, createRoomPacketId));
}).detach();
const를 사용할 수 있으면 모든 곳에 사용하라는 어떤 유튜버의 조언이 떠올랐다.