亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在Go中關閉自動進紙通道

在Go中關閉自動進紙通道

Go
慕森卡 2021-04-02 22:19:59
我正在嘗試使用Go中的并發性和渠道。我面臨的問題主要是并發性,因此,我并沒有放棄以下邏輯錯誤或應更改的邏輯。我有一個緩沖通道,其緩沖大小為“ N”,它還表示將要創建的goroutine的數量。所有例程都從一個通道讀取并在另一個通道中寫入,而主要的goroutine將從最后一個通道中打印值。1個輸入通道--- N個goroutines查找并添加到輸入和輸出--- 1個輸出通道問題是我總是陷入僵局,因為我不知道如何關閉正在饋送自身的通道,也不知道何時停止,因此我也無法關閉輸出通道。該代碼是以下示例:package mainconst count = 3const finalNumber = 100// There will be N routines running and reading from the one read channel// The finalNumber is not known, in this examples is 100, but in the main problem will keep self feeding until the operation gives a wrong output// readingRoutine will feed read channel and the print channelfunc readingRoutine(read, print chan int) {    for i := range read {        print <- i        if i < finalNumber && i+count < finalNumber {            read <- i + count        }    }}// This is the main routine that will be printing the values from the print channelfunc printingRoutine(print chan int) {    for i := range print {        println(i)    }}func main() {    read := make(chan int, count)    print := make(chan int, count)    // Feed count numbers into the buffered channel    for i := 0; i < count; i++ {        read <- i    }    // count go routines will be processing the read channel    for i := 0; i < count; i++ {        go readingRoutine(read, print)    }    printingRoutine(print)}在此示例中,它應打印從0到100的所有數字并完成。謝謝
查看完整描述

2 回答

?
牧羊人nacy

TA貢獻1862條經驗 獲得超7個贊

我通常會發現,如果您在使設計模式或想法可行時遇到真正的問題,那說明您做錯了。在這種情況下,自給式例行程序的想法知道何時應關閉自身。


我認為您正在尋找的是的想法worker pool。


本質上,您有一個包含的集合的通道,work然后是workersgo例程形式的多個例程,它們從該通道讀取作業并對其進行處理,直到完成所有工作為止。


在以下示例中,我使用包gopool運行3個并發工作程序,這些工作程序由第4個go例程提供。


我等待所有工人關閉自己,這是由于輸入工作通道被關閉而造成的。


// create the channel to store the jobs

// notice that we can only have 5 jobs in the channel at one time

workChan := make(chan int, 5)


// here we define what should be happening in each of our workers.

// each worker will be running concurrently

var work gopool.WorkFunc = func(ctx context.Context) error {

    for {

        select {

        case <-ctx.Done():

            // this is just a get out clause in case we want to prematurely stop the workers while there is still work to do

            return ctx.Err()

        case work, ok := <-workChan:

            if !ok {

                // we get here if the work channel has been closed

                return nil

            }

            // do something with work here

            fmt.Println(work)

        }

    }

}


// this func defines how many workers we want to be running concurrently

var workerCount gopool.WorkerCountFunc = func() uint64 {

    return 3

}


// here we define a new worker pool

p := gopool.NewPool("test", work, workerCount, nil, context.TODO())


// here we start the worker pool

cancel, err := p.StartOnce()

if err != nil {

        panic(err)

}


// the workers are now running and waiting for jobs


// we'll defer the cancel to make sure that the pool will be closed eventually

defer cancel()


// now we'll start a go routine to feed the workers

// it does this by adding to the workChan, and closes workChan when there is no more work to do

// when the workChan is closed the workers know that they should quit

go func(workChan chan<- int, min int, max int) {

    for i := min; i <= max; i++ {

        workChan <- i

    }

    close(workChan)

}(workChan, 3, 200)


// now we wait for the pool to be finished with it's work

<-p.Done()


fmt.Println("all work has been done")

輸出示例:


$ go run main.go 

4

6

7

8

9

10

3

5

13

14

15

16

17

18

12

20

21

19

23

24

25

22

27

28

11

30

31

26

33

29

35

36

34

38

39

32

41

42

37

44

43

46

47

40

49

50

51

52

48

54

53

56

57

58

45

60

61

62

63

64

65

55

59

68

69

66

71

72

73

70

75

76

77

67

79

80

74

82

83

81

85

84

87

88

89

78

91

90

93

94

92

96

97

95

99

98

101

102

103

104

100

106

107

108

109

105

111

112

110

114

115

116

117

118

119

120

86

122

123

124

125

126

127

121

129

113

131

128

133

134

130

136

137

132

139

138

141

140

143

144

145

146

147

148

149

150

135

151

153

142

155

156

157

158

159

160

161

162

163

164

152

154

167

165

166

170

171

172

173

174

169

176

177

178

179

180

168

182

183

184

181

185

187

188

189

190

175

186

193

191

195

194

197

196

199

198

200

192

all work has been done


查看完整回答
反對 回復 2021-04-19
  • 2 回答
  • 0 關注
  • 232 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號