• Stars
    star
    1,406
  • Rank 33,444 (Top 0.7 %)
  • Language
    Shell
  • License
    Apache License 2.0
  • Created about 10 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pure C implementation of Go channels.

chan

Pure C implementation of Go channels.

Unbuffered Channels

Unbuffered channels provide both a mechanism for communication as well as synchronization. When data is sent into the channel, the sender blocks until a receiver is ready. Likewise, a receiver will block until a sender is ready.

#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("%s\n", msg);

    // Clean up channel.
    chan_dispose(chan);
}

With an unbuffered channel, the sender and receiver are synchronized, so the above program will print ping.

Buffered Channels

Buffered channels accept a limited number of values without a corresponding receiver for those values. Sending data will not block unless the channel is full. Receiving data will block only if the channel is empty.

#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("%s\n", msg);

    chan_recv(chan, &msg);
    printf("%s\n", msg);

    // Clean up channel.
    chan_dispose(chan);
}

The above program will print buffered and then channel. The sends do not block because the channel has a capacity of 2. Sending more after that would block until values were received.

Closing Channels

When a channel is closed, no more values can be sent on it. Receiving on a closed channel will return an indication code that the channel has been closed. This can be useful to communicate completion to the channelโ€™s receivers. If the closed channel is buffered, values will be received on it until empty.

#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 %d\n", (int) job);
    }

    // Notify that all jobs were received.
    printf("received all jobs\n");
    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 %d\n", i);
    }
    chan_close(jobs);
    printf("sent all jobs\n");

    // Wait for all jobs to be received.
    chan_recv(done, NULL);

    // Clean up channels.
    chan_dispose(jobs);
    chan_dispose(done);
}

This program will print:

sent job 1
received job 1
sent job 2
received job 2
sent job 3
received job 3
sent all jobs
received all jobs

Select Statements

Select statements choose which of a set of possible send or receive operations will proceed. They also provide a way to perform non-blocking sends and receives. Selects are particularly useful for multiplexing communication over several channels.

#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 %s\n", msg);
            break;
        default:
            printf("no message received\n");
    }

    // A non-blocking send works similarly.
    msg = "foo";
    switch(chan_select(NULL, 0, NULL, &messages, 1, &msg))
    {
        case 0:
            printf("sent message %s\n", msg);
            break;
        default:
            printf("no message sent\n");
    }

    // 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 %s\n", msg);
            break;
        case 1:
            printf("received signal %s\n", msg);
            break;
        default:
            printf("no activity\n");
    }

    // Clean up channels.
    chan_dispose(messages);
    chan_dispose(signals);
}

This program will print:

no message received
no message sent
no activity

More Repositories

1

comcast

Simulating shitty network connections so you can build better systems.
Go
10,309
star
2

BoomFilters

Probabilistic data structures for processing continuous, unbounded streams.
Go
1,594
star
3

BigQuery-Python

Simple Python client for interacting with Google BigQuery.
Python
456
star
4

bench

A generic latency benchmarking library.
Go
310
star
5

Flotilla

Automated message queue orchestration for scaled-up benchmarking.
Go
236
star
6

mq-benchmarking

Performance benchmarks for various message queues.
Go
192
star
7

CS-Literature-of-the-Day

A curated list of computer science literature, updated daily.
164
star
8

go-benchmarks

A few miscellaneous Go microbenchmarks.
Go
147
star
9

fast-topic-matching

Messaging middleware topic matching implementations.
Go
75
star
10

nanomsg-service-discovery

Service-discovery pattern implemented with nanomsg.
Python
25
star
11

gatling

Minimal pub/sub message queue in C.
C
22
star
12

Zinc

Real-time distributed messaging and document synchronization.
Java
15
star
13

InverseBloomFilter

Concurrent inverse Bloom filter.
Go
13
star
14

PubSub-Python

Simple Python client for interacting with Google Cloud Pub/Sub.
Python
9
star
15

log-benchmarking

Benchmarking for distributed logs.
Go
9
star
16

OpenGL-Playground

Playing with OpenGL.
C
8
star
17

thrift-nats

Thrift RPC over NATS.
Go
8
star
18

go-fast

Material for 'So You Wanna Go Fast?' Strange Loop talk
Go
8
star
19

hdrhistogram-writer

API for writing HdrHistograms in a readable format consumable by http://hdrhistogram.github.io/HdrHistogram/plotFiles.html.
Go
7
star
20

go-zab

Go implementation of ZooKeeper Atomic Broadcast.
Go
7
star
21

Dalvik-Baksmali

Android library for disassembling DEX files using baksmali.
Java
7
star
22

nats-leader-election

Leader election implemented with Raft over NATS.
Go
6
star
23

httpmonitor

CLI tool for monitoring HTTP traffic.
Go
5
star
24

kaput.io

Laws of General Systemantics.
CSS
5
star
25

sync

Some basic synchronization primitives.
C
4
star
26

rdcss

RDCSS double-compare-single-swap.
Go
4
star
27

dockerfiles

Contain yourself.
Shell
3
star
28

gae-circleci-java

Example Java Spring app running on Google App Engine deployed from CircleCI.
Java
2
star
29

uthread

C
2
star
30

dexmaker

Java
2
star
31

gatling-gun

Go client for gatling broker.
Go
2
star
32

matchboxd

Replicated matchbox server (https://github.com/Workiva/matchbox)
Go
2
star
33

vessel

Fast, asynchronous client-server messaging.
Go
2
star
34

SQLAlchemyUtils

Useful utilities for working with SQLAlchemy.
Python
2
star
35

TrendBlotter

The world talks, we listen.
JavaScript
2
star
36

vessel.js

Vessel messaging client.
JavaScript
2
star
37

gaeutils

Useful utilities for working with Google App Engine.
Python
1
star
38

crapchat

A janky and obnoxious chat application.
Go
1
star
39

Jockey

Seamless Google App Engine authentication for Android.
Java
1
star
40

type-ahead-search

Toy type-ahead search.
Java
1
star
41

nimbus

Nim
1
star
42

zk-select

Go
1
star
43

dotfiles

The most exciting thing you will ever see.
Vim Script
1
star
44

pipe-sem

C
1
star
45

webhook-test

webhook test
Python
1
star
46

frugal

Java
1
star
47

jump-consistent-hash

Go implementation of Jump Consistent Hash.
Go
1
star
48

config-parser

A simple API for parsing ini-like configuration files.
1
star