我正在使用 Golang,我正在嘗試使這個程式執行緒安全。它將一個數字作為引數(即要啟動的消費者任務的數量),從輸入中讀取行數,并累積字數。我希望執行緒是安全的(但我不希望它只鎖定所有內容,它需要高效)我應該使用通道嗎?我該怎么做呢?
package main
import (
"bufio"
"fmt"
"log"
"os"
"sync"
)
// Consumer task to operate on queue
func consumer_task(task_num int) {
fmt.Printf("I'm consumer task #%v ", task_num)
fmt.Println("Line being popped off queue: " queue[0])
queue = queue[1:]
}
// Initialize queue
var queue = make([]string, 0)
func main() {
// Initialize wait group
var wg sync.WaitGroup
// Get number of tasks to run from user
var numof_tasks int
fmt.Print("Enter number of tasks to run: ")
fmt.Scan(&numof_tasks)
// Open file
file, err := os.Open("test.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// Scanner to scan the file
scanner := bufio.NewScanner(file)
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
// Loop through each line in the file and append it to the queue
for scanner.Scan() {
line := scanner.Text()
queue = append(queue, line)
}
// Start specified # of consumer tasks
for i := 1; i <= numof_tasks; i {
wg.Add(1)
go func(i int) {
consumer_task(i)
wg.Done()
}(i)
}
wg.Wait()
fmt.Println("All done")
fmt.Println(queue)
}
uj5u.com熱心網友回復:
您在 slice 上存在資料競爭queue。并發 goroutines,當從佇列頭部彈出元素以通過sync.Mutex鎖以受控方式執行此操作時。或者使用通道來管理作業項的“佇列”。
要將您必須使用的內容轉換為使用通道,請更新作業人員以將輸入通道作為您的佇列 - 并在通道上設定范圍,以便每個作業人員可以處理多個任務:
func consumer_task(task_num int, ch <-chan string) {
fmt.Printf("I'm consumer task #%v\n", task_num)
for item := range ch {
fmt.Printf("task %d consuming: Line item: %v\n", task_num, item)
}
// each worker will drop out of their loop when channel is closed
}
從切片更改queue為通道并以如下方式提供專案:
queue := make(chan string)
go func() {
// Loop through each line in the file and append it to the queue
for scanner.Scan() {
queue <- scanner.Text()
}
close(queue) // signal to workers that there is no more items
}()
然后只需更新您的作業調度程式代碼以添加通道輸入:
go func(i int) {
consumer_task(i, queue) // add the queue parameter
wg.Done()
}(i)
https://go.dev/play/p/AzHyztipUZI
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/447425.html
