정해놨던 클라이언트 연결 방식을 실제로 구현하고 있다.
우선 DB쪽은 개설하기도 어렵거니와 따로 공부를 해야하는 파트이기 때문에 return true함수를 만들어 사용하고 있고
나머지 큐작업~ 실제 통신까지 구현을 했다.
우선 나는 이 프로그램을 수많은 사용자가 사용할 것이고 여러대의 컴퓨터에서 이 프로그램을 가동해서 io를 처리한다는 가정하에 개발을 진행하고 있다.
그렇다보니 쓰레드 작업이 가끔 여러번 겹쳐서 복잡해 질 때가 있다.
지난번에 작성했던 포인터 손실 현상도 사실 쓰레드에 관련된 문제였다.
이번엔 오늘 발생했던 쓰레드 프로그래밍에 대한 기본적인 실수를 적어보려한다.
while (stop_ev_.wait_for(std::chrono::microseconds(100)) == std::future_status::timeout) {
mtx.lock();
size_t sl_sz = session_list.size(); ----- *
mtx.unlock();
if (sl_sz > 0) { ----- **
thread client_thread([=]() {
mtx.lock();
session* session_ptr_ = session_list.front();
session_list.pop_front(); ----- ***
auto cli_ep = session_ptr_->cli_socket;
mtx.unlock();
tcp::socket client_handle = session_ptr_->accept_client(cli_ep);
});
client_thread.detach(); ----- ****
}
}
세션 풀을 가동시키는 코드 중 일부이다.
*에서 현재 대기큐에 있는 세션 갯수를 갱신하고
**에서 숫자를 계산하여
***에서 처리할 세션을 복사하고 리스트에서 제거하는 코드이다.
이 코드의 문제점은 ****이다.
client_thread를 만들고 detach코드를 작동시켰으므로 저 쓰레드 코드는 별도로 독립하여 작동하게 된다.
즉, 바깥 코드와 별도로 실행되므로 session_list.pop_front()코드가 동작하기 전에 session_list.size()를 조회한다면 팝 되기 전의 세션 리스트 사이즈가 조회 될 것이고
이후 생성되는 쓰레드에서는 pop_front()코드를 실행 할 때 이전과 같은 세션을 끌어오거나 최악의 경우, 비어있는 세션에서 pop_front코드를 실행해 서버가 멈추게 될 것이다.
싱글 쓰레드에서 작업할 때에는 고려할 이유가 없었던 부분들이다.
내일부터는 에러코드와 결과코드에 대해서 작성할 예정이기 때문에(ㅠㅠ) 당분간 쓰레드 코드는 작성 할 일이 없지만
쓰레드 코드 작업은 항상 여러번 검토하며 진행해야겠다.
'프로젝트 > bankserver' 카테고리의 다른 글
[c++/boost::asio] Bank Server 개발일기 (0) | 2020.04.26 |
---|---|
[c++/boost::asio] Bank Server 개발일기 (0) | 2020.04.17 |
[c++/boost::asio] 개발 일기 (0) | 2020.04.16 |
시작 (0) | 2020.04.10 |