Methods for inter-thread communication in C include: shared memory, synchronization mechanism (mutex lock, condition variable), pipeline, and message queue. For example, use a mutex lock to protect a shared counter: declare a mutex lock (m) and a shared variable (counter); each thread updates the counter by locking (lock_guard); ensure that only one thread updates the counter at a time to prevent race conditions.
In a multi-threaded application, threads need to be able to communicate with each other to coordinate tasks and share data. C provides a variety of mechanisms to implement inter-thread communication, including:
Using shared memory, multiple threads can access the same memory area. This is a low-overhead approach, but care needs to be taken to avoid race conditions.
int shared_data = 0; void thread_1() { shared_data++; // 可能会被其他线程同时访问 } void thread_2() { shared_data++; // 可能会同时导致不正确的结果 }
The synchronization mechanism can be used to coordinate threads when accessing shared resources.
Mutex locks provide mutually exclusive access, ensuring that only one thread can access shared resources at a time.
std::mutex m; void thread_1() { std::lock_guard<std::mutex> l(m); // 获取互斥锁 // 访问共享资源 } void thread_2() { std::lock_guard<std::mutex> l(m); // 获取互斥锁 // 访问共享资源 }
Condition variables allow threads to wait for specific conditions to be met.
std::condition_variable cv; std::mutex m; void producer() { std::lock_guard<std::mutex> l(m); // 获取互斥锁 while (!condition) { // 等待条件满足 cv.wait(l); } // 生产数据 } void consumer() { std::lock_guard<std::mutex> l(m); // 获取互斥锁 condition = true; cv.notify_all(); // 唤醒所有等待线程 }
Pipeline is a unidirectional communication mechanism used to transmit data between two threads.
std::pipe pipe; void writer() { std::string message = "hello"; std::write(pipe[1], message.c_str(), message.length()); } void reader() { std::string message; std::read(pipe[0], message.data(), message.size()); }
Message Queue provides an asynchronous message delivery mechanism.
key_t key = ftok("message_queue", 'a'); int message_queue = msgget(key, IPC_CREAT | 0666); void sender() { Message msg; msg.mtext = "hello"; msgsnd(message_queue, &msg, sizeof(msg.mtext), IPC_NOWAIT); } void receiver() { Message msg; msgrcv(message_queue, &msg, sizeof(msg.mtext), 0, 0); }
Practical case: Using a mutex to protect a shared counter
Suppose we have a shared counter that needs to be updated concurrently by multiple threads. We can protect this counter using a mutex:
std::mutex m; int counter = 0; void thread_1() { for (int i = 0; i < 1000000; i++) { std::lock_guard<std::mutex> l(m); counter++; } } void thread_2() { for (int i = 0; i < 1000000; i++) { std::lock_guard<std::mutex> l(m); counter--; } }
This ensures that only one thread can update the counter at any given time, thus preventing race conditions.
The above is the detailed content of C++ Concurrent Programming: How to handle inter-thread communication?. For more information, please follow other related articles on the PHP Chinese website!