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