Search
Duplicate
🔂

C++에서 전역변수 대신 싱글톤 기법을 사용해보기

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
C++
디자인 패턴
태그
Scrap
8 more properties
서버 프로세스에 signal이 들어오면 연결된 클라이언트들에게 종료 프로토콜을 보내고 안정적으로 종료시켜야 할 필요성을 느꼈다.
시그널 핸들러에 들어갈 수 있는 인자는 시그널 숫자인 int 형 하나만 들어갈 수 있다. 그래서 보통 전역변수를 이용해서 서버를 종료시키기 위한 값을 설정해서 종료시킨다.
하지만 싱글톤(Singleton) 이라는 기법을 이용하면 전역변수가 없어도 어디서든 접근할 수 있는 객체를 만들 수 있다. 그리고 그 객체는 무조건 하나만 존재할 수 있다.
유지보수에 좋을지 모르겠지만 궁금하니까 한번 써보자!
signal이 들어와서 종료시켜야할 때 목표는 2가지다.
1.
연결된 클라이언트들에게 시그널 정보를 담은 종료 프로토콜 메시지를 보내고 연결을 끊게 한다.
2.
Server 객체의 status를 off 시켜서 false로 만든 다음 루프문을 빠져나오게 한다. 그렇게 소멸자를 통해 서버를 안정적으로 종료시키는 것이다.
싱글톤 객체에 Server 객체에 접근할 수 있는 포인터를 담아서 어디서든 Server 객체에 접근할 수 있게 하면 된다. Server 객체가 Protocol 객체에도 접근할 수 있으므로 프로토콜도 보낼 수 있다.
그렇게 만든 Singleton class는 아래와 같다.
Server 포인터를 담을 수 있는 Singleton class의 모습
getInstance()라는 static 멤버함수 안에 Singleton 객체를 static으로 선언했다. 프로세스 생성 초기에 Singleton 객체가 생성되고 언제든 이 static 멤버함수를 호출하면 사용할 수 있다.
생성자를 private 안에 두었기 때문에 외부에서는 Singleton 객체를 만들 수 없다. static으로 선언된 instance는 생성 초기에 단 한번만 만들어지고 getInstance() 멤버함수에서만 선언했기 때문에 프로세스 내에서 단 하나만 존재할 수 있다.
Singleton class의 데이터에 Server 객체의 포인터를 담아서 Server 객체에 접근할 수 있도록 했다. 아래와 같이 singleton_equip_server() 라는 함수를 이용해서 저장했다.
Singleton 안의 getInstance() static 멤버 함수는 namespace를 이용해서 어디서든 호출할 수 있다. 함수 안에 Singleton referencegetInstance()return 값으로 초기화해서 사용할 수 있다.
아래에서 signal이 들어왔을 때 시그널 핸들러 안에서 Singleton reference를 이용해서 목표들을 처리했다.
signal 함수와 signal 핸들러
서버를 구동하고 SIGINT가 들어왔을 때 모습
Singleton reference를 통해 Server 객체에 접근한 다음 연결된 클라이언트들에게 종료 프로토콜을 보내고 disconnect 요청을 보냈다. 그리고 서버의 statusoff 시켜서 소멸자를 호출하고 안정적으로 종료시켰다.
서버에 SIGINT가 들어왔을 때, 클라이언트 프로그램에서 종료 프로토콜인 Closing link를 받은 모습. 메시지 안에 SIGINT 정보가 들어있다.
클라이언트와 연결하고 나서 서버에 SIGINT가 들어와서 종료할 때, 클라이언트가 종료 프로토콜을 받고 메시지 안에 시그널에 대한 정보도 들어있는 것을 확인할 수 있다.
※ 참고서적