• Stars
    star
    1,406
  • Rank 33,453 (Top 0.7 %)
  • Language
    Shell
  • License
    Apache License 2.0
  • Created over 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