Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 有没有什么优雅的方式可以暂停并继续其他的社交活动?_Go_Channel_Goroutine - Fatal编程技术网

Go 有没有什么优雅的方式可以暂停并继续其他的社交活动?

Go 有没有什么优雅的方式可以暂停并继续其他的社交活动?,go,channel,goroutine,Go,Channel,Goroutine,在我的例子中,我有数千个goroutine作为work()同时工作。我还有一个sync()goroutine。当sync启动时,我需要任何其他goroutine在同步作业完成后暂停一段时间。这是我的密码: var channels []chan int var channels_mutex sync.Mutex func work() { channel := make(chan int, 1) channels_mutex.Lock() channels = append(c

在我的例子中,我有数千个goroutine作为
work()
同时工作。我还有一个
sync()
goroutine。当
sync
启动时,我需要任何其他goroutine在同步作业完成后暂停一段时间。这是我的密码:

var channels []chan int
var channels_mutex sync.Mutex

func work() {
  channel := make(chan int, 1)
  channels_mutex.Lock()  
  channels = append(channels, channel)
  channels_mutex.Unlock()
  for {
    for {
      sync_stat := <- channel // blocked here
      if sync_stat == 0 { // if sync complete
        break  
      }
    }
    // Do some jobs
    if (some condition) {
      return
    }
  }
}

func sync() {
  channels_mutex.Lock()
  // do some sync

  for int i := 0; i != len(channels); i++ {
    channels[i] <- 0
  }
  channels_mutex.Unlock()
}
var通道[]通道int
变量通道\u互斥同步。互斥
func工作(){
通道:=制造(通道内部,1)
通道\u互斥锁
通道=附加(通道,通道)
通道\u互斥锁。解锁()
为了{
为了{

sync_stat:=如果我理解正确,您需要N个工作进程和一个控制器,可以随意暂停、恢复和停止工作进程。下面的代码将实现这一点

package main

import (
    "fmt"
    "runtime"
    "sync"
)

// Possible worker states.
const (
    Stopped = 0
    Paused  = 1
    Running = 2
)

// Maximum number of workers.
const WorkerCount = 1000

func main() {
    // Launch workers.
    var wg sync.WaitGroup
    wg.Add(WorkerCount + 1)

    workers := make([]chan int, WorkerCount)
    for i := range workers {
        workers[i] = make(chan int, 1)

        go func(i int) {
            worker(i, workers[i])
            wg.Done()
        }(i)
    }

    // Launch controller routine.
    go func() {
        controller(workers)
        wg.Done()
    }()

    // Wait for all goroutines to finish.
    wg.Wait()
}

func worker(id int, ws <-chan int) {
    state := Paused // Begin in the paused state.

    for {
        select {
        case state = <-ws:
            switch state {
            case Stopped:
                fmt.Printf("Worker %d: Stopped\n", id)
                return
            case Running:
                fmt.Printf("Worker %d: Running\n", id)
            case Paused:
                fmt.Printf("Worker %d: Paused\n", id)
            }

        default:
            // We use runtime.Gosched() to prevent a deadlock in this case.
            // It will not be needed of work is performed here which yields
            // to the scheduler.
            runtime.Gosched()

            if state == Paused {
                break
            }

            // Do actual work here.
        }
    }
}

// controller handles the current state of all workers. They can be
// instructed to be either running, paused or stopped entirely.
func controller(workers []chan int) {
    // Start workers
    setState(workers, Running)

    // Pause workers.
    setState(workers, Paused)

    // Unpause workers.
    setState(workers, Running)

    // Shutdown workers.
    setState(workers, Stopped)
}

// setState changes the state of all given workers.
func setState(workers []chan int, state int) {
    for _, w := range workers {
        w <- state
    }
}
主程序包
进口(
“fmt”
“运行时”
“同步”
)
//可能的工人国家。
常数(
停止=0
暂停=1
运行=2
)
//工人的最大数量。
常数工作计数=1000
func main(){
//发射工人。
var wg sync.WaitGroup
工作组添加(工作计数+1)
工人:=制造([]成交量,工人计数)
对于i:=范围工人{
工人[i]=制造(chan int,1)
go func(i int){
工人(i,工人[i])
wg.Done()
}(一)
}
//启动控制器例行程序。
go func(){
管制员(工人)
wg.Done()
}()
//等待所有goroutine完成。
wg.Wait()
}

func工人(id int,ws What do`使用通道进行通信是Go中实现这一点的惯用方法。如果您愿意,可以使用全局变量。但是我建议不要使用
sync.Mutex
来锁定它。在处理大量goroutine时,它们的伸缩性不太好,每个goroutine都会获取R/W锁。在这种情况下,我将使用e> sync/atomic
package以原子方式读取/写入状态。@jimt很好的示例;很好地提醒了当通道被阻塞时“默认”是如何运行的。我要补充的是,如果工作人员有时需要一段时间才能返回读取状态,那么最好让与他们对话的通道具有1的缓冲区,这样您就可以在同一时间内写入所有通道快点,不要暂停或停止2号,直到1号停止,等等。或者我误解了它的工作原理吗?也许我遗漏了一些东西,但暂停的工作人员不会继续运行(由于选择的默认部分)。我认为这将导致大量的unnec.线程上下文切换。是的,它将继续进入默认情况,但它并不像您预期的那样昂贵。它的作用是将
状态设置为适当的值。这取决于您决定是否以及如何限制循环。就上下文切换而言,非常彻底的e解释这在围棋中是如何工作的。