<p>I see this in open source library sometimes</p>
<pre><code>func (struct *myStruct) Main() {
tcpListener, err := net.Listen("tcp", struct.getOpts().TCPAddress)
struct.Lock()
struct.tcpListener = tcpListener
struct.Unlock()
httpsListener, err = tls.Listen("tcp", struct.getOpts().HTTPSAddress, struct.tlsConfig)
struct.Lock()
struct.httpsListener = httpsListener
struct.Unlock()
}
</code></pre>
<p>Is it idiomatic to lock when setting up listener for tcp and https in main for golang, what kind of situation will you reach race condition?</p>
<hr/>**评论:**<br/><br/>peterbourgon: <pre><p>Locking is necessary when multiple goroutines may be accessing the struct (or, more accurately, its members) concurrently. But without more context, this is not good code, because you generally shouldn't be manually calling Lock and Unlock like this. Where did you find this code?</p></pre>Thaxll: <pre><p>There: <a href="https://github.com/nsqio/nsq/blob/master/nsqd/nsqd.go#L209" rel="nofollow">https://github.com/nsqio/nsq/blob/master/nsqd/nsqd.go#L209</a></p></pre>jerf: <pre><p>Examining this code, I don't think the locks are necessary. It doesn't look to me like the <code>Main()</code> function they are embedded in is expected to be re-entrant, so normally I'd expect that this is using, for lack of a better term, the "initialize read-only and-then multithread" pattern. That is, it is common (I find) in Go for a particular goroutine to set up a struct without using locks on the struct and without sharing that struct, and then for there to be a single point at which all that initialization is done and then the struct is multi-threading safe, because all the values are read-only after that point and therefore don't need locks. In that case I wouldn't expect <code>Main()</code> here to be using locks, because at that point I would expect that only one goroutine could possibly be running.</p>
<p>Part of the reason I expect that is that otherwise that code above is, if not wrong, at least very dangerous. If multiple things are running through <code>Main()</code> at once, that code above runs the risk of having the tcpListener from one goroutine win, while the httpsListener from another goroutine wins. Because of the fact that listening ports are themselves a sort of a lock (as the OS enforces that) and the fact the rest of the code in that function will <code>os.Exit(1)</code> if acquiring the port fails (which is reasonable on its own for a server), I infer that in practice multiple goroutines are not running through this code as that would cause the program to fail intermittently, but routinely, at startup.</p>
<p>Personally, I'd remove those locks and document more clearly what is being used when. You could justify the use of locks that way with a handwave at being paranoid, but I'd personally rather see it correct and well-documented than merely paranoid. YMMV (no sarcasm; there's a time and a place for paranoia).</p></pre>glhfggkkthxbye: <pre><p>I don't totally agree with the code, but the locking is fine. The locks are encapsulated within the struct. The code creates a new listener, and upon successful creation locks a race vulrenable resource(the resources encapsulated in the struct), then assigns the listener to the struct, and unlocks - all the functionality is contained within the struct.</p>
<p>Why add another wrapper func within this initialization func? For more overhead? Or for more indirection?</p></pre>
[Newbie Question] Why do you need to lock when setting up tcp and https listener
polaris · · 428 次点击这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传