[c++] C++에서의 스레드 간 메시지 전달 방법

C++에서 멀티스레딩 환경에서 스레드 간에 메시지를 안전하게 전달하는 방법은 여러 가지가 있습니다. 여기서는 가장 일반적으로 사용되는 세 가지 방법에 대해 살펴보겠습니다.

1. Mutex와 조건 변수(Condition Variables) 사용

가장 기본적인 방법은 Mutex(상호배제 기능)와 조건 변수를 사용하는 것입니다. 메시지를 보내고 받을 때마다 Mutex를 이용하여 상호배제를 구현하고, 조건 변수를 사용하여 스레드 간에 신호를 주고 받습니다.

예제 코드:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool data_ready = false;
int message;

void sender() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lock(mtx);
        message = 100;
        data_ready = true;
    }
    cv.notify_one();
}

void receiver() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []{ return data_ready; });
    std::cout << "Received message: " << message << std::endl;
}

int main() {
    std::thread t1(sender);
    std::thread t2(receiver);

    t1.join();
    t2.join();

    return 0;
}

2. 스레드 세이프 큐 사용

두 번째 방법은 스레드 세이프 큐(Thread-safe Queue)를 사용하는 것입니다. 큐를 이용하여 하나의 스레드에서 데이터를 넣고, 다른 스레드에서 데이터를 뺄 수 있도록 구현합니다.

예제 코드:

#include <iostream>
#include <thread>
#include <mutex>
#include <queue>

std::mutex mtx;
std::queue<int> message_queue;

void sender() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::lock_guard<std::mutex> lock(mtx);
    message_queue.push(100);
}

void receiver() {
    std::lock_guard<std::mutex> lock(mtx);
    if (!message_queue.empty()) {
        int message = message_queue.front();
        message_queue.pop();
        std::cout << "Received message: " << message << std::endl;
    }
}

int main() {
    std::thread t1(sender);
    std::thread t2(receiver);

    t1.join();
    t2.join();

    return 0;
}

3. C++11 스레드 지원 라이브러리 사용

마지막으로, C++11에서는 스레드 지원을 위한 라이브러리가 제공됩니다. std::thread, std::async, std::future 등의 클래스를 사용하여 스레드 간에 메시지를 주고 받을 수 있습니다.

예제 코드:

#include <iostream>
#include <thread>
#include <future>

void sender(std::promise<int> &prms) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    prms.set_value(100);
}

void receiver(std::future<int> &fut) {
    int message = fut.get();
    std::cout << "Received message: " << message << std::endl;
}

int main() {
    std::promise<int> prms;
    std::future<int> fut = prms.get_future();

    std::thread t1(sender, std::ref(prms));
    std::thread t2(receiver, std::ref(fut));

    t1.join();
    t2.join();

    return 0;
}

C++에서 스레드 간 메시지 전달을 위한 다양한 방법을 사용할 수 있지만, 상황에 맞게 적절한 방법을 선택하여 사용해야 합니다.

참고 문헌: