基于Pthreads线程库的实现
cpp
g++ your_program.cpp -lpthread
编译时确保链接了Pthreads库.
cpp
#include <pthread.h>
#include <iostream>
#include <unistd.h>
// 全局变量,用于控制打印顺序
int turn = 0;
// 定义互斥锁和条件变量
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void* printA(void* arg) {
for (int i = 0; i < 10; i++) {
pthread_mutex_lock(&lock);
while (turn != 0) {
pthread_cond_wait(&cond, &lock);
}
std::cout << "A ";
turn = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&lock);
}
return NULL;
}
void* printB(void* arg) {
for (int i = 0; i < 10; i++) {
pthread_mutex_lock(&lock);
while (turn != 1) {
pthread_cond_wait(&cond, &lock);
}
std::cout << "B ";
turn = 2;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&lock);
}
return NULL;
}
void* printC(void* arg) {
for (int i = 0; i < 10; i++) {
pthread_mutex_lock(&lock);
while (turn != 2) {
pthread_cond_wait(&cond, &lock);
}
std::cout << "C ";
turn = 0;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main() {
pthread_t t1, t2, t3;
pthread_create(&t1, NULL, printA, NULL);
pthread_create(&t2, NULL, printB, NULL);
pthread_create(&t3, NULL, printC, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
return 0;
}
互斥锁和条件变量
cpp
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
using namespace std;
class PrintABC {
public:
PrintABC(int count) : count_(count) { }
void printA () {
for (int i = 0; i < count_; ++i) {
std::unique_lock<std::mutex> lock(mtx_);
//等待turn_变为0
cv_.wait(lock, [this]() { return turn_ == 0; });
std::cout << "a" << endl;
//设置下一个轮次为1,并通知等待的线程
turn_ = 1;
cv_.notify_all();
}
}
void printB () {
for (int i = 0; i < count_; ++i) {
std::unique_lock<std::mutex> lock(mtx_);
//等待turn_变为0
cv_.wait(lock, [this]() { return turn_ == 1; });
std::cout << "b" << endl;
//设置下一个轮次为1,并通知等待的线程
turn_ = 2;
cv_.notify_all();
}
}
void printC () {
for (int i = 0; i < count_; ++i) {
std::unique_lock<std::mutex> lock(mtx_);
//等待turn_变为0
cv_.wait(lock, [this]() { return turn_ == 2; });
std::cout << "c" << endl;
//设置下一个轮次为1,并通知等待的线程
turn_ = 0;
cv_.notify_all();
}
}
private:
std::mutex mtx_;
std::condition_variable cv_;
int turn_ = 0; //控制打印顺序,0代表打印a,1代表打印b,2代表打印c,
int count_; //打印次数
};
int main () {
int printCount = 10; //设定打印次数
PrintABC printABC(printCount);
std::thread t1(&PrintABC::printA, &printABC);
std::thread t2(&PrintABC::printB, &printABC);
std::thread t3(&PrintABC::printC, &printABC);
t1.join();
t2.join();
t3.join();
return 0;
}
原子变量
无锁实现控制打印顺序,但会占用更多的CPU资源,因为线程在等待时处于忙等(busy-waiting)状态。
cpp
#include <iostream>
#include <thread>
#include <atomic>
volatile std::atomic<int> turn(0);
void printA(int count) {
for (int i = 0; i < count; ++i) {
while(turn != 0); // 忙等
std::cout << "a";
turn = 1;
}
}
void printB(int count) {
for (int i = 0; i < count; ++i) {
while(turn != 1); // 忙等
std::cout << "b";
turn = 2;
}
}
void printC(int count) {
for (int i = 0; i < count; ++i) {
while(turn != 2); // 忙等
std::cout << "c";
turn = 0;
}
}
int main() {
int count = 10;
std::thread a(printA, count);
std::thread b(printB, count);
std::thread c(printC, count);
a.join();
b.join();
c.join();
std::cout << "\n";
return 0;
}
信号量
C++20之后引入的库,才使得C++语言级别的信号量实现,
编译的时候记得加一个-std=c++20
cpp
#include <iostream>
#include <thread>
#include <semaphore>
std::counting_semaphore semA(1); // 初始计数为1,A可以立即打印
std::counting_semaphore semB(0); // 初始计数为0,B需要等待A释放
std::counting_semaphore semC(0); // 初始计数为0,C需要等待B释放
void printA(int count) {
for (int i = 0; i < count; ++i) {
semA.acquire();
std::cout << "a" << std::endl;
semB.release();
}
}
void printB(int count) {
for (int i = 0; i < count; ++i) {
semB.acquire();
std::cout << "b" << std::endl;
semC.release();
}
}
void printC(int count) {
for (int i = 0; i < count; ++i) {
semC.acquire();
std::cout << "c" << std::endl;
semA.release();
}
}
int main() {
int count = 10; // 每个线程打印10次
std::thread a(printA, count);
std::thread b(printB, count);
std::thread c(printC, count);
a.join();
b.join();
c.join();
std::cout << "\n";
return 0;
}