TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Show HN: Chan – pure C implementation of Go channels

150 pointsby tylertreatover 10 years ago

13 comments

epsover 10 years ago
Good stuff, thanks for sharing. Random comments based on a quick glance through the code if I may.<p><pre><code> chan_t* chan_init(int capacity); </code></pre> should be &quot;size_t capacity&quot;, since negative capacity values are invalid. This also eliminated the need for the first check in the function.<p><pre><code> chan-&gt;buffered </code></pre> is duplicate in meaning to chan-&gt;queue being non-NULL.<p>Why chan&#x27;s mutexes and pcond are malloc&#x27;ed and not included in chan&#x27;s struct? They are also not freed when channel is disposed, unless I&#x27;m missing something. Mutexes are also not destroyed when buffered chan is disposed, but they <i>are</i> created for it.<p>(Edit)<p>Also, my biggest nitpick would be that chan_t structure should really not be in chan.h header since it&#x27;s meant to be transparent to the app and the API operates exclusively with pointers to chan_t. Then, if it is made private (read - internal to the implementation), then you can divorce buffered and unbuffered channels into two separate structs, allocate required one and then multiplex between them in calls that treat buffered and unbuffered channels differently. I.e.<p><pre><code> struct chan_t { &#x2F;&#x2F; Shared properties pthread_mutex_t m_mu; pthread_cond_t m_cond; int closed; &#x2F;&#x2F; Type int buffered; }; struct chan_unbuffered_t { struct chan_t base; pthread_mutex_t r_mu; pthread_mutex_t w_mu; int readers; blocking_pipe_t* pipe; }; ... </code></pre> or better yet, just include a handful of function pointers into chan_t for each of the API methods that need more than the shared part of chan_t struct, initialize them on allocation and put type-specific code in these functions. It will make for a more compact, concise and localized code.<p>(Edit 2)<p>Here&#x27;s what I mean with function pointers - <a href="https://gist.github.com/anonymous/5f97d8db71776b188820" rel="nofollow">https:&#x2F;&#x2F;gist.github.com&#x2F;anonymous&#x2F;5f97d8db71776b188820</a> - basically poor man&#x27;s inheritance and virtual methods :)
评论 #8244928 未加载
评论 #8245443 未加载
kersnyover 10 years ago
Libtask[1] by Russ Cox (one of the creators of Go) may provide some inspiration. It implements channels but uses coroutines instead of threading. As a consequence it has some cool stuff like networking and it does all of the hard parts of saving&#x2F;restoring registers for task switching.<p>[1]: <a href="http://swtch.com/libtask/" rel="nofollow">http:&#x2F;&#x2F;swtch.com&#x2F;libtask&#x2F;</a>
评论 #8245997 未加载
评论 #8245727 未加载
评论 #8245652 未加载
sreanover 10 years ago
Quick question: isn&#x27;t channel&#x27;s raison d&#x27;etre the fact that they need not be backed by system threads, that they are considerably cheaper and one can fire tens of thousands of them without worrying too much about performance. In other words aren&#x27;t they primarily intended as a tool for solving a concurrency problem rather than a parallelism problem.<p>Although, as far as I recall Go does map a bundle of them to a thread and can thus handle parallelism as well.<p>Just to clarify, this is not a complaint, I am trying to get a better idea of these abstractions.<p>@tylertreat<p>&gt; I believe you&#x27;re confusing goroutines with channels. Goroutines are lightweight threads of execution. Channels are the pipes that connect goroutines.<p>That is indeed correct. I was thinking more in the line of fibres that meld the concepts of a coroutine and a channel into a single abstraction. So the idea is Chan connects threads rather than coroutines.
评论 #8245165 未加载
评论 #8245132 未加载
edsiper2over 10 years ago
One of our students[0] at Monkey Project Organization[1] through Google Summer of Code[2], wrote a complete co-routine implementation for the Duda I&#x2F;O[3] Web Services stack.<p>The feature is called &quot;dthread&quot; or &quot;duda-thread&quot; which aims to expose Channels and generic co-routines functionalities, you can check the following relevant links:<p>a. The co-routine implementation:<p><a href="https://github.com/monkey/duda/blob/master/src/duda_dthread.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;monkey&#x2F;duda&#x2F;blob&#x2F;master&#x2F;src&#x2F;duda_dthread....</a><p>it does not need mutex or anything similar, short code but a lot of thinking behind it.<p>b. Example: web service to calculate Fibonacci using channels:<p><a href="https://github.com/monkey/duda-examples/blob/master/080_dthread_fibonacci/main.c" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;monkey&#x2F;duda-examples&#x2F;blob&#x2F;master&#x2F;080_dthr...</a><p>the whole work will be available on our next stable release, if someone want to give it a try, just drop us a line.<p>[0] <a href="http://blog-swpd.rhcloud.com" rel="nofollow">http:&#x2F;&#x2F;blog-swpd.rhcloud.com</a><p>[1] <a href="http://monkey-project.com" rel="nofollow">http:&#x2F;&#x2F;monkey-project.com</a><p>[2] <a href="http://www.google-melange.com" rel="nofollow">http:&#x2F;&#x2F;www.google-melange.com</a><p>[3] <a href="http://duda.io" rel="nofollow">http:&#x2F;&#x2F;duda.io</a>
评论 #8246102 未加载
arjovrover 10 years ago
The circle is now complete... Plan 9 from user space implementation of channels. <a href="http://swtch.com/usr/local/plan9/include/thread.h" rel="nofollow">http:&#x2F;&#x2F;swtch.com&#x2F;usr&#x2F;local&#x2F;plan9&#x2F;include&#x2F;thread.h</a>
Rapzidover 10 years ago
Here is some interesting reading: <a href="http://golang.org/src/pkg/runtime/chan.goc" rel="nofollow">http:&#x2F;&#x2F;golang.org&#x2F;src&#x2F;pkg&#x2F;runtime&#x2F;chan.goc</a> Go&#x27;s implementation <a href="https://docs.google.com/document/d/1yIAYmbvL3JxOKOjuCyon7JhW4cSv1wy5hC0ApeGMV9s/pub" rel="nofollow">https:&#x2F;&#x2F;docs.google.com&#x2F;document&#x2F;d&#x2F;1yIAYmbvL3JxOKOjuCyon7JhW...</a> Dmitry&#x27;s &quot;Go channels on steroids&quot; post
评论 #8245515 未加载
mseepgoodover 10 years ago
<a href="http://plan9.bell-labs.com/magic/man2html/2/thread" rel="nofollow">http:&#x2F;&#x2F;plan9.bell-labs.com&#x2F;magic&#x2F;man2html&#x2F;2&#x2F;thread</a>
BrandonMover 10 years ago
I think you need to add<p><pre><code> pthread_cond_destroy(&amp;chan-&gt;m_cond); </code></pre> After <a href="https://github.com/tylertreat/chan/blob/master/src/chan.c#L136" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;tylertreat&#x2F;chan&#x2F;blob&#x2F;master&#x2F;src&#x2F;chan.c#L1...</a>
copxover 10 years ago
&gt; #include &lt;pthread.h&gt;<p>That is not &quot;pure C&quot;. &quot;pthread.h&quot; (POSIX threads) is not part of the C language standard, it is a system-specific header commonly found on UNIX systems. Windows has a different threading system for example.
评论 #8245163 未加载
评论 #8245106 未加载
chi42over 10 years ago
Pretty nifty. I like the names of the functions chan_can_recv() and chan_can_send(). Made me think think of the old cooking show &quot;Yan Can Cook.&quot;
WalterBrightover 10 years ago
Very nice. Any chance of Boost licensing it?
vhost-over 10 years ago
This is pretty awesome. I do a lot of Go and C and this just might come in handy. Thanks for sharing!
SeoxySover 10 years ago
How does this compare to using ZeroMQ inproc sockets?