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 计数避免资源竞争

全部评论

相关推荐

头像 会员标识 头像
04-09 15:47
Java
点赞 评论 收藏
转发
3 16 评论
分享
牛客网
牛客企业服务