Golang如何编写并发程序并同步处理结果

Golang如何编写并发程序并同步处理结果 早上好, 为了开发一个新的共识算法(区块链共识),

  1. 两个矿工必须竞争运行一个程序(处理任务)
  2. 每个矿工完成其必须执行的处理任务后,将其结果与其他矿工的结果同步
  3. 选择并显示找到的最大结果 此致
3 回复

你的具体问题是什么?让程序并发运行并处理同步,这在很大程度上取决于你程序的算法。

更多关于Golang如何编写并发程序并同步处理结果的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我们的目标是编写一个由多个(网络)节点执行的并发程序 g,在执行结束时,每个节点广播其结果。

在Go中实现这种并发竞争和结果同步,典型的做法是使用goroutine和channel。以下是一个示例实现:

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// 模拟矿工处理任务
func minerWorker(id int, wg *sync.WaitGroup, resultChan chan<- int) {
	defer wg.Done()
	
	// 模拟计算耗时
	processingTime := time.Duration(rand.Intn(1000)) * time.Millisecond
	time.Sleep(processingTime)
	
	// 生成随机结果(模拟挖矿结果)
	result := rand.Intn(1000)
	fmt.Printf("矿工 %d 完成处理,结果: %d,耗时: %v\n", id, result, processingTime)
	
	// 发送结果到channel
	resultChan <- result
}

func main() {
	rand.Seed(time.Now().UnixNano())
	
	const numMiners = 2
	var wg sync.WaitGroup
	resultChan := make(chan int, numMiners)
	
	// 启动矿工goroutine
	for i := 1; i <= numMiners; i++ {
		wg.Add(1)
		go minerWorker(i, &wg, resultChan)
	}
	
	// 等待所有矿工完成
	go func() {
		wg.Wait()
		close(resultChan)
	}()
	
	// 收集并比较结果
	var results []int
	for result := range resultChan {
		results = append(results, result)
	}
	
	// 找出最大结果
	if len(results) > 0 {
		maxResult := results[0]
		for _, result := range results {
			if result > maxResult {
				maxResult = result
			}
		}
		fmt.Printf("\n所有矿工结果: %v\n", results)
		fmt.Printf("最大结果: %d\n", maxResult)
	}
}

如果需要更精确的同步控制,可以使用sync.WaitGroup配合互斥锁:

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

type Miner struct {
	ID     int
	Result int
}

func main() {
	rand.Seed(time.Now().UnixNano())
	
	const numMiners = 2
	var wg sync.WaitGroup
	var mu sync.Mutex
	var miners []Miner
	
	// 启动矿工竞争
	for i := 1; i <= numMiners; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			
			// 模拟处理时间
			processingTime := time.Duration(rand.Intn(1000)) * time.Millisecond
			time.Sleep(processingTime)
			
			// 生成结果
			result := rand.Intn(1000)
			
			// 安全地存储结果
			mu.Lock()
			miners = append(miners, Miner{ID: id, Result: result})
			mu.Unlock()
			
			fmt.Printf("矿工 %d 完成,结果: %d\n", id, result)
		}(i)
	}
	
	// 等待所有矿工完成
	wg.Wait()
	
	// 找出最大结果
	if len(miners) > 0 {
		maxResult := miners[0].Result
		winnerID := miners[0].ID
		
		for _, miner := range miners {
			if miner.Result > maxResult {
				maxResult = miner.Result
				winnerID = miner.ID
			}
		}
		
		fmt.Printf("\n矿工 %d 获胜,最大结果: %d\n", winnerID, maxResult)
		fmt.Printf("所有结果: ")
		for _, miner := range miners {
			fmt.Printf("矿工%d=%d ", miner.ID, miner.Result)
		}
		fmt.Println()
	}
}

对于区块链共识算法的实际场景,你可能需要更复杂的同步机制。这里是一个使用context处理超时的版本:

package main

import (
	"context"
	"fmt"
	"math/rand"
	"sync"
	"time"
)

func minerTask(ctx context.Context, id int, resultChan chan<- int) {
	// 模拟挖矿计算
	select {
	case <-time.After(time.Duration(rand.Intn(1500)) * time.Millisecond):
		result := rand.Intn(1000)
		fmt.Printf("矿工 %d 找到区块,哈希值: %d\n", id, result)
		resultChan <- result
	case <-ctx.Done():
		fmt.Printf("矿工 %d 超时\n", id)
		resultChan <- -1
	}
}

func main() {
	rand.Seed(time.Now().UnixNano())
	
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()
	
	resultChan := make(chan int, 2)
	
	// 启动两个矿工竞争
	go minerTask(ctx, 1, resultChan)
	go minerTask(ctx, 2, resultChan)
	
	// 收集结果
	var results []int
	for i := 0; i < 2; i++ {
		select {
		case result := <-resultChan:
			if result != -1 {
				results = append(results, result)
			}
		case <-ctx.Done():
			fmt.Println("共识超时")
		}
	}
	
	// 选择最大结果
	if len(results) > 0 {
		maxResult := results[0]
		for _, result := range results {
			if result > maxResult {
				maxResult = result
			}
		}
		fmt.Printf("共识达成,最大哈希值: %d\n", maxResult)
	} else {
		fmt.Println("未达成共识")
	}
}

这些示例展示了Go中并发竞争、结果同步和比较的基本模式。在实际的区块链共识算法中,你需要根据具体的共识规则(如PoW、PoS等)调整任务逻辑和同步机制。

回到顶部