在多线程编程中,线程间的通信是确保程序正确运行和高效协同的关键。掌握操作系统提供的线程间通信(Inter-Thread Communication,简称ITC)技巧,能够显著提升程序的执行效率和稳定性。本文将详细介绍几种常见的线程间通信方法,并探讨如何在实际编程中应用它们。
1. 等待/通知机制
等待/通知机制是线程间通信最基本的方式,它允许一个线程在某个条件不满足时等待,而另一个线程可以在条件满足时通知等待的线程。
1.1 条件变量
条件变量是一种同步机制,允许线程在某个条件不满足时挂起,并在条件满足时被唤醒。在C++中,可以使用std::condition_variable来实现。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void thread1() {
std::unique_lock<std::mutex> lck(mtx);
std::cout << "Thread 1 is waiting..." << std::endl;
cv.wait(lck, []{return ready;});
std::cout << "Thread 1 is notified!" << std::endl;
}
void thread2() {
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<std::mutex> lck(mtx);
ready = true;
}
cv.notify_one();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
1.2 互斥锁
互斥锁(Mutex)可以保证同一时刻只有一个线程可以访问共享资源。在C++中,可以使用std::mutex来实现。
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void thread1() {
std::lock_guard<std::mutex> lck(mtx);
std::cout << "Thread 1 is running..." << std::endl;
}
void thread2() {
std::lock_guard<std::mutex> lck(mtx);
std::cout << "Thread 2 is running..." << std::endl;
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
2. 信号量
信号量(Semaphore)是一种更高级的同步机制,它可以允许多个线程同时访问共享资源。在C++中,可以使用std::semaphore来实现。
#include <iostream>
#include <thread>
#include <semaphore>
std::semaphore sem(2);
void thread1() {
std::this_thread::sleep_for(std::chrono::seconds(1));
sem.acquire();
std::cout << "Thread 1 is running..." << std::endl;
sem.release();
}
void thread2() {
std::this_thread::sleep_for(std::chrono::seconds(2));
sem.acquire();
std::cout << "Thread 2 is running..." << std::endl;
sem.release();
}
int main() {
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
3. 管道
管道(Pipe)是一种用于线程间通信的机制,它允许一个线程将数据发送到另一个线程。在C++中,可以使用std::pipe来实现。
#include <iostream>
#include <thread>
#include <unistd.h>
int pipefd[2];
void thread1() {
char buffer[10];
write(pipefd[1], "Hello", 5);
read(pipefd[0], buffer, 10);
std::cout << "Thread 1 received: " << buffer << std::endl;
}
void thread2() {
char buffer[10];
write(pipefd[1], "World", 5);
read(pipefd[0], buffer, 10);
std::cout << "Thread 2 received: " << buffer << std::endl;
}
int main() {
if (pipe(pipefd) == -1) {
std::cerr << "Pipe creation failed" << std::endl;
return 1;
}
std::thread t1(thread1);
std::thread t2(thread2);
t1.join();
t2.join();
return 0;
}
总结
掌握操作系统提供的线程间通信技巧,能够帮助开发者编写出高效、稳定的程序。本文介绍了等待/通知机制、信号量和管道三种常见的线程间通信方法,并提供了相应的C++代码示例。在实际编程中,应根据具体需求选择合适的通信方式,以提高程序的性能和可靠性。
