有没有其他方法可以显示WaitGroup的进程?

huangapple go评论86阅读模式
英文:

Is there another way to make WaitGroup showed the process?

问题

这是我运行整个worker的代码片段

for w := 1; w <= *totalworker; w++ {
	wg.Add(1)
	go worker(w, jobs, results, dir, &wg)
}

这是我的Worker

func worker(id int, jobs <-chan [][]string, results chan<- [][]string, dir *string, wg *sync.WaitGroup) {
	defer wg.Done()
	for j := range jobs {
		filename := j[0][4] + ".csv"
		fmt.Printf("\nWorker %d starting a job\n", id)
		//results <- j //to show The result of jobs, unnecessary
		fmt.Printf("\nWorker %d Creating %s.csv\n", id, j[0][4])
		CreateFile(dir, &filename, j)
		fmt.Printf("\nWorker %d Finished creating %s.csv on %s\n", id, j[0][4], *dir)
		fmt.Printf("\nWorker %d finished a job\n", id)
	}
}

当我不使用WaitGroup运行时,它只会创建我所需的一部分文件。但它会显示进程。它会显示worker1执行任务,worker2执行任务等等...因此,直到程序结束,它会显示每个任务。

另外,使用WaitGroup时,它会创建我所需的全部文件。但是,它会完全一次性完成,而不显示进程。当我使用WaitGroup运行它时,它只会以...等等,等待,整个过程在哪里xD结束,它只会在程序结束时显示worker1执行任务,worker2执行任务等等...

有没有办法让WaitGroup显示每个打印输出?

英文:

This is my Snippet Code to run the whole worker

for w := 1; w &lt;= *totalworker; w++ {
		wg.Add(1)
		go worker(w, jobs, results, dir, &amp;wg)
	}

This was my Worker

	defer wg.Done()
	for j := range jobs {
		filename := j[0][4] + &quot;.csv&quot;
		fmt.Printf(&quot;\nWorker %d starting a job\n&quot;, id)
		//results &lt;- j //to show The result of jobs, unnecessary
		fmt.Printf(&quot;\nWorker %d Creating %s.csv\n&quot;, id, j[0][4])
		CreateFile(dir, &amp;filename, j)
		fmt.Printf(&quot;\nWorker %d Finished creating %s.csv on %s\n&quot;, id, j[0][4], *dir)
		fmt.Printf(&quot;\nWorker %d finished a job\n&quot;, id)
	}
}

When i run without WaitGroup it will only create a few of the whole file i needed. but It show the process of it. It show worker1 do job, worker2 do job etc... so until the end of program it will show each of it.

Otherwise, with waitgroup it create the whole file i need. But, its completely do all in one without show the process, show when i run it with WaitGroup it just ended like ... wait where is the whole process xD, it just ended with showing Worker1 do job, worker2 do job etc... at End of program.

Is there any thing i can do with this Waitgroup so it show each of its print?

答案1

得分: 1

你需要创建一些通道来监听前一个通道是否完成,就像这样,这是我的例子,我有20个例程,它们将同时处理一些逻辑,并按原始顺序返回:

package channel

import (
	"fmt"
	"sync"
	"time"
)


func Tests() {

	c := make(map[int]chan bool)

	var wg sync.WaitGroup

	// 总的例程数
	loop := 20

	// 在第几步停止
	stop := 11

	for i := 1; i <= loop; i++ {
		// 初始化通道
		c[i] = make(chan bool)
	}

	for i := 1; i <= loop; i++ {
		wg.Add(1)
		go func(c map[int]chan bool, i int) {
			defer wg.Done()

			// 逻辑步骤
			fmt.Println("处理逻辑步骤", i)

			if i == 1 {
				fmt.Println("发送第一个消息", i)
				c[i] <- true // 立即发送通知给下一步
			} else {
				select {
				case channel := <-c[i-1]:
					defer close(c[i-1])

					if channel == true {
						// 立即发送
						fmt.Println("发送消息", i)
						// 未发送
						if i < loop { // 修复通道未写入时的死锁问题

							if i == stop && stop > 0 {
								c[i] <- false // 在第i步停止
							} else {
								c[i] <- true // 立即发送通知给下一步
							}
						}
					} else {
						// 未发送
						if i < loop { // 修复通道未写入时的死锁问题
							c[i] <- false
						}
					}
				}
			}
		}(c, i)
	}
	wg.Wait()
	fmt.Println("到达这里")
	//time.Sleep(3 * time.Second)go run
	fmt.Println("结束")
}

希望对你有帮助!

英文:

You need create some channels to listening what previous channel is completed like that, this my example I have 20 routines, they will process some logic at the same time, and return in original order:

package channel
import (
&quot;fmt&quot;
&quot;sync&quot;
&quot;time&quot;
)
func Tests() {
c := make(map[int]chan bool)
var wg sync.WaitGroup
// total go routine
loop := 20
// stop in step
stop := 11
for i := 1; i &lt;= loop; i++ {
// init channel
c[i] = make(chan bool)
}
for i := 1; i &lt;= loop; i++ {
wg.Add(1)
go func(c map[int]chan bool, i int) {
defer wg.Done()
// logic step
fmt.Println(&quot;Process Logic step &quot;, i)
if i == 1 {
fmt.Println(&quot;Sending message first &quot;, i)
c[i] &lt;- true // send now notify to next step
} else {
select {
case channel := &lt;-c[i-1]:
defer close(c[i-1])
if channel == true {
// send now
fmt.Println(&quot;Sending message &quot;, i)
// not sent
if i &lt; loop { // fix deadlock when channel doesnt write
if i == stop &amp;&amp; stop &gt; 0 {
c[i] &lt;- false // stop in step i
} else {
c[i] &lt;- true // send now notify to next step
}
}
} else {
// not send
if i &lt; loop { // fix deadlock when channel doesnt write
c[i] &lt;- false
}
}
}
}
}(c, i)
}
wg.Wait()
fmt.Println(&quot;go here &quot;)
//time.Sleep(3 * time.Second)go run
fmt.Println(&quot;End&quot;)
}

huangapple
  • 本文由 发表于 2022年1月4日 10:18:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/70573439.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定