👉🏻 아래는 터미널에서 몇가지 명령어로 while루프를 탈출하는 로직입니다.
Below is the logic to exit a while loop using a few commands in the terminal.
👉🏻 run_cmd() 함수 내에서 /exit 명령어가 들어오면 running플래그를 false로 바꿔서 루프를 탈출합니다.
If the /exit command is encountered inside the run_cmd() function, the running flag is changed to false to exit the loop.
👉🏻 코드 / Code
✔️ Server.cpp
#include <iostream>
#include <string>
#include <functional>
#include <vector>
#include <thread>
#include <atomic> // ❗️
// -- Exit Logic -- //
class Server {
public:
std::atomic<bool> running{false};
std::function<std::string(const std::string&)> logic_handler;
void set_handler(std::function<std::string(const std::string&)> handler) {
logic_handler = handler;
}
void receive_request(const std::string& message) {
std::cout << "[Server] 요청 받음/Receive Request: " << message << std::endl;
if (logic_handler) {
std::string response = logic_handler(message);
std::cout << "[Server] 응답 보냄/Send Response: " << response << "\n" << std::endl;
}
}
// 서버의 메인 로직이 돌아가는 루프
// Loop where the server's main logic runs
void run() {
std::cout << "[INFO] 메인 루프 시작..." << std::endl;
std::cout << "[INFO] Main loop started..." << std::endl;
while (running.load()) { // ❗️
int count = 0;
// 실제 서버라면 여기서 네트워크 패킷을 기다리거나 작업을 처리합니다.
// If it were a real server, it would wait for network packets or process tasks here.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << "[INFO] 메인 루프가 종료되었습니다." << std::endl;
std::cout << "[INFO] The main loop has finished." << std::endl;
}
void cmd_run() {
std::string command;
while (true) {
std::cout << "CMD> ";
if (!std::getline(std::cin, command)) break;
if (command.empty()) continue;
if (command == "/exit" || command == "exit") {
std::cout << "[INFO] 종료 명령 감지. 플래그를 변경합니다.\n";
std::cout << "[INFO] Exit command detected. Changing flags.\n";
// running 플래그를 false로 만들어 run()의 while문을 탈출하게 함
// Set the running flag to false to exit the while loop in run()
running.store(false); // ❗️
break;
} else if (command == "/status") {
std::cout << "[STATUS] 실행 상태/running status: " << (running.load() ? "Running" : "Stopped") << "\n";
} else {
// 일반 명령어 입력 시 logic_handler 실행 예시
// Example of executing logic_handler when a standard command is entered
receive_request(command);
}
}
}
};
std::string router(const std::string& msg) {
if (msg == "aloy") return "horizon";
if (msg == "silverhand") return "cyberpunk";
return "unknown command";
}
int main() {
Server my_sv;
//
// 리턴(출력): 맨 앞에 있는 std::string
// 입력(인자): 괄호 () 안에 있는 const std::string&
// Return (Output): The std::string at the beginning
// Input (Argument): The const std::string& inside the parentheses ()
// my_sv.set_handler(router);
my_sv.set_handler([&](const std::string& req) {
return router(req);
});
// 서버를 시작 상태로 변경 / Set the server to running state
my_sv.running.store(true);
// run() 메서드를 별도의 쓰레드에서 실행 (비동기) / Run the run() method in a separate thread (asynchronous)
std::thread worker(&Server::run, &my_sv);
// 메인 쓰레드에서 명령어 입력 대기 / Wait for command input in the main thread
my_sv.cmd_run();
// cmd_run이 종료되면 worker 쓰레드가 끝날 때까지 기다림(join)
//.Wait for the worker thread to finish when cmd_run exits
if (worker.joinable()) {
worker.join();
}
std::cout << "[MAIN] 프로그램이 완전히 종료되었습니다." << std::endl;
std::cout << "[MAIN] The program has completely terminated." << std::endl;
return 0;
}
✔️ 컴파일 / Compiling
g++ server.cpp -o server -std=c++17 -pthread
✔️ 실행 / Run
MacBookAir loop_exit_logic % ./server
CMD> [INFO] 메인 루프 시작...
[INFO] Main loop started...
CMD> aloy
[Server] 요청 받음/Receive Request: aloy
[Server] 응답 보냄/Send Response: horizon
CMD> test
[Server] 요청 받음/Receive Request: test
[Server] 응답 보냄/Send Response: unknown command
CMD> silverhand
[Server] 요청 받음/Receive Request: silverhand
[Server] 응답 보냄/Send Response: cyberpunk
CMD> /exit
[INFO] 종료 명령 감지. 플래그를 변경합니다.
[INFO] Exit command detected. Changing flags.
[INFO] 메인 루프가 종료되었습니다.
[INFO] The main loop has finished.
[MAIN] 프로그램이 완전히 종료되었습니다.
[MAIN] The program has completely terminated.
MacBookAir loop_exit_logic %