Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
G
go-ipfs
概览
概览
详情
活动
周期分析
版本库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
jihao
go-ipfs
Commits
7a785ded
提交
7a785ded
authored
9月 18, 2014
作者:
Juan Batiz-Benet
提交者:
Brian Tiger Chow
9月 22, 2014
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
sync counter for processing things
上级
25d0ce8f
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
118 行增加
和
0 行删除
+118
-0
counter.go
util/todocounter/counter.go
+118
-0
没有找到文件。
util/todocounter/counter.go
0 → 100644
浏览文件 @
7a785ded
package
todocounter
import
(
"sync"
)
// Counter records things remaining to process. It is needed for complicated
// cases where multiple goroutines are spawned to process items, and they may
// generate more items to process. For example, say a query over a set of nodes
// may yield either a result value, or more nodes to query. Signaling is subtly
// complicated, because the queue may be empty while items are being processed,
// that will end up adding more items to the queue.
//
// Use Counter like this:
//
// todos := make(chan int, 10)
// ctr := todoctr.NewCounter()
//
// process := func(item int) {
// fmt.Println("processing %d\n...", item)
//
// // this task may randomly generate more tasks
// if rand.Intn(5) == 0 {
// todos<- item + 1
// ctr.Increment(1) // increment counter for new task.
// }
//
// ctr.Decrement(1) // decrement one to signal the task being done.
// }
//
// // add some tasks.
// todos<- 1
// todos<- 2
// todos<- 3
// todos<- 4
// ctr.Increment(4)
//
// for {
// select {
// case item := <- todos:
// go process(item)
// case <-ctr.Done():
// fmt.Println("done processing everything.")
// close(todos)
// }
// }
type
Counter
interface
{
// Incrememnt adds a number of todos to track.
// If the counter is **below** zero, it panics.
Increment
(
i
uint32
)
// Decrement removes a number of todos to track.
// If the count drops to zero, signals done and destroys the counter.
// If the count drops **below** zero, panics. It means you have tried to remove
// more things than you added, i.e. sync issues.
Decrement
(
i
uint32
)
// Done returns a channel to wait upon. Use it in selects:
//
// select {
// case <-ctr.Done():
// // done processing all items
// }
//
Done
()
<-
chan
struct
{}
}
type
todoCounter
struct
{
count
int32
done
chan
struct
{}
sync
.
RWMutex
}
// NewSyncCounter constructs a new counter
func
NewSyncCounter
()
Counter
{
return
&
todoCounter
{
done
:
make
(
chan
struct
{}),
}
}
func
(
c
*
todoCounter
)
Increment
(
i
uint32
)
{
c
.
Lock
()
defer
c
.
Unlock
()
if
c
.
count
<
0
{
panic
(
"counter already signaled done. use a new counter."
)
}
// increment count
c
.
count
+=
int32
(
i
)
}
// Decrement removes a number of todos to track.
// If the count drops to zero, signals done and destroys the counter.
// If the count drops **below** zero, panics. It means you have tried to remove
// more things than you added, i.e. sync issues.
func
(
c
*
todoCounter
)
Decrement
(
i
uint32
)
{
c
.
Lock
()
defer
c
.
Unlock
()
if
c
.
count
<
0
{
panic
(
"counter already signaled done. probably have sync issues."
)
}
if
int32
(
i
)
>
c
.
count
{
panic
(
"decrement amount creater than counter. sync issues."
)
}
c
.
count
-=
int32
(
i
)
if
c
.
count
==
0
{
// done! signal it.
c
.
count
--
// set it to -1 to prevent reuse
close
(
c
.
done
)
// a closed channel will always return nil
}
}
func
(
c
*
todoCounter
)
Done
()
<-
chan
struct
{}
{
return
c
.
done
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论