chan
v0.0.4
纯C实施GO频道。
未封闭的通道既提供了通信和同步的机制。当数据发送到频道时,发件人块直到接收器准备就绪为止。同样,接收器将阻止直到发件人准备就绪。
#include <pthread.h>
#include <stdio.h>
#include "chan.h"
chan_t * chan ;
void * ping ()
{
// Send blocks until receiver is ready.
chan_send ( chan , "ping" );
return NULL ;
}
int main ()
{
// Initialize unbuffered channel.
chan = chan_init ( 0 );
pthread_t th ;
pthread_create ( & th , NULL , ping , NULL );
// Receive blocks until sender is ready.
void * msg ;
chan_recv ( chan , & msg );
printf ( "%sn" , msg );
// Clean up channel.
chan_dispose ( chan );
}使用未封闭的通道,发件人和接收器已同步,因此上述程序将打印ping 。
缓冲通道接受有限数量的值,而这些值没有相应的接收器。除非通道已满,否则发送数据将不会阻止。仅当通道为空时,接收数据才会阻止。
#include <stdio.h>
#include "chan.h"
int main ()
{
// Initialize buffered channel with a capacity of 2.
chan_t * chan = chan_init ( 2 );
// Send up to 2 values without receiver.
chan_send ( chan , "buffered" );
chan_send ( chan , "channel" );
// Later receive the values.
void * msg ;
chan_recv ( chan , & msg );
printf ( "%sn" , msg );
chan_recv ( chan , & msg );
printf ( "%sn" , msg );
// Clean up channel.
chan_dispose ( chan );
}上面的程序将打印buffered ,然后channel 。发送不会阻止,因为通道的容量为2。在此之后发送更多的发送将阻止直到收到值。
关闭通道时,不再可以在其上发送更多值。在封闭的通道上接收将返回通道已关闭的指示代码。这对于将完成与频道的接收器传达可能很有用。如果封闭的通道被缓冲,将在其上接收值,直到空。
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include "chan.h"
chan_t * jobs ;
chan_t * done ;
void * worker ()
{
// Process jobs until channel is closed.
void * job ;
while ( chan_recv ( jobs , & job ) == 0 )
{
printf ( "received job %dn" , ( int ) job );
}
// Notify that all jobs were received.
printf ( "received all jobsn" );
chan_send ( done , "1" );
return NULL ;
}
int main ()
{
// Initialize channels.
jobs = chan_init ( 5 );
done = chan_init ( 0 );
pthread_t th ;
pthread_create ( & th , NULL , worker , NULL );
// Send 3 jobs over the jobs channel then close it.
int i ;
for ( i = 1 ; i <= 3 ; i ++ )
{
chan_send ( jobs , ( void * ) ( uintptr_t ) i );
printf ( "sent job %dn" , i );
}
chan_close ( jobs );
printf ( "sent all jobsn" );
// Wait for all jobs to be received.
chan_recv ( done , NULL );
// Clean up channels.
chan_dispose ( jobs );
chan_dispose ( done );
}该程序将打印:
sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs
选择语句选择将继续进行哪一组可能的发送或接收操作。他们还提供了执行非阻滞发送和接收的方法。选择对于在多个渠道上多路复用沟通特别有用。
#include <stdio.h>
#include "chan.h"
chan_t * messages ;
chan_t * signals ;
int main ()
{
// Initialize channels.
messages = chan_init ( 0 );
signals = chan_init ( 0 );
void * msg ;
// This is a non-blocking receive. If a value is available on messages,
// select will take the messages (0) case with that value. If not, it will
// immediately take the default case.
switch ( chan_select ( & messages , 1 , & msg , NULL , 0 , NULL ))
{
case 0 :
printf ( "received message %sn" , msg );
break ;
default :
printf ( "no message receivedn" );
}
// A non-blocking send works similarly.
msg = "foo" ;
switch ( chan_select ( NULL , 0 , NULL , & messages , 1 , & msg ))
{
case 0 :
printf ( "sent message %sn" , msg );
break ;
default :
printf ( "no message sentn" );
}
// We can use multiple cases above the default clause to implement a
// multi-way non-blocking select. Here we attempt non-blocking receives on
// both messages and signals.
chan_t * chans [ 2 ] = { messages , signals };
switch ( chan_select ( chans , 2 , & msg , NULL , 0 , NULL ))
{
case 0 :
printf ( "received message %sn" , msg );
break ;
case 1 :
printf ( "received signal %sn" , msg );
break ;
default :
printf ( "no activityn" );
}
// Clean up channels.
chan_dispose ( messages );
chan_dispose ( signals );
}该程序将打印:
no message received
no message sent
no activity