Untitled

 avatar
unknown
c_cpp
24 days ago
2.1 kB
6
Indexable
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <string>
#include <functional>
#include <atomic>

// Thread-safe queue (Channel)
template <typename T>
class Channel {
public:
    void send(const T& value) {
        {
            std::lock_guard<std::mutex> lock(mtx_);
            queue_.push(value);
        }
        cv_.notify_one(); // Notify waiting thread
    }

    bool receive(T& value) {
        std::unique_lock<std::mutex> lock(mtx_);
        cv_.wait(lock, [this]() { return !queue_.empty() || !running_; }); // Wait for data or shutdown
        if (!queue_.empty()) {
            value = queue_.front();
            queue_.pop();
            return true;
        }
        return false; // Indicate shutdown
    }

    void shutdown() {
        {
            std::lock_guard<std::mutex> lock(mtx_);
            running_ = false;
        }
        cv_.notify_all(); // Wake up all waiting threads
    }

private:
    std::queue<T> queue_;
    std::mutex mtx_;
    std::condition_variable cv_;
    bool running_ = true;
};

// Goroutine function: processes messages indefinitely
void goroutine(Channel<std::string>& channel) {
    while (true) {
        std::string message;
        if (!channel.receive(message)) {
            // Shutdown signal received
            break;
        }
        // Process the message
        std::cout << "Processing: " << message << std::endl;
    }
    std::cout << "Thread shutting down gracefully." << std::endl;
}

int main() {
    Channel<std::string> channel;
    std::atomic<bool> running(true);

    // Start a thread to act as the goroutine
    std::thread worker(goroutine, std::ref(channel));

    // Send messages to the thread
    channel.send("Task 1");
    channel.send("Task 2");
    channel.send("Task 3");

    // Simulate waiting for tasks
    std::this_thread::sleep_for(std::chrono::seconds(2));

    // Stop the thread gracefully
    channel.shutdown();

    // Wait for the thread to finish
    worker.join();

    return 0;
}
Leave a Comment