C++ 和 Go 语言实现两个线程交替打印数字 1-10
- C ++ 实现
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
using namespace std;
mutex mut; // 定义互斥量
condition_variable cond1, cond2; // 定义两个条件变量,不同线程等待不同的条件变量
int num = 1;
void thread1() {
while (num <= 10) {
unique_lock<mutex> locker(mut); // 使用 unique_lock 锁管理类,自动上锁和解锁
cout << "thread1: " << num << endl;
num++;
cond2.notify_one(); // 线程 1 打印完成,通知线程 2 打印
cond1.wait(locker); // 等待线程 2 打印完成再继续打印
}
}
void thread2() {
while (num <= 10) {
unique_lock<mutex> locker(mut);
cout << "thread2: " << num << endl;
num++;
cond1.notify_one();
cond2.wait(locker);
}
}
int main() {
thread t1(thread1); // 定义两个线程
thread t2(thread2);
t1.join(); // 回收线程资源
t2.join();
system("pause");
return 0;
}
思路:两个线程分别使用两个不同的条件变量控制,共同等待用一个互斥量,从而实现交替打印的效果
- Go 实现 1
package main
import (
"fmt"
"sync"
)
const (
MAX = 10 // 最大打印到多少
GoCount = 2 // 同时执行的线程数
)
func main() {
fmt.Println(Solution(MAX, GoCount))
}
func Solution(MAX int, GoCount int) []int {
wg := sync.WaitGroup{}
wg.Add(GoCount)
res := make([]int, 0)
count := 1
for i := 0; i < GoCount; i++ {
go func(k int) { // 注意需要传递参数到协程内
for {
now := count
if now > MAX {
wg.Done()
return
}
// 这条语句保证任务均匀地分配到所有的协程
// now 是当前的任务编号,GoCount 是协程的数量,k 是当前协程的编号。
if now%GoCount == k {
res = append(res, now)
count++
}
}
}(i)
}
wg.Wait()
return res
}
- Go 实现 2
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
ch1 := make(chan bool)
ch2 := make(chan bool)
go func() {
count := 1
for count < 10 {
<-ch1
fmt.Println("groutine 1: ", count)
count = count + 2
ch2 <- true
}
wg.Done()
}()
go func() {
count := 2
for count <= 10 {
<-ch2
fmt.Println("groutine 2: ", count)
count = count + 2
if count <= 10 {
ch1 <- true
}
}
wg.Done()
}()
ch1 <- true
wg.Wait()
}
思路:两个 channel 分别控制两个协程,两个 count 计数避免资源竞争

查看16道真题和解析