#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// ---------- class KeyRingBuffer ---------->
struct KeyRingBuffer {
int* buffer;
int buffer_len;
int write_index;
int read_index;
};
// struct KeyRingBuffer 型の(初期化された)インスタンスを得る。
struct KeyRingBuffer* new_KeyRingBuffer(int buffer_len)
{
struct KeyRingBuffer* a = (struct KeyRingBuffer*)malloc(sizeof(*a));
a->buffer = (int*)malloc(sizeof(*(a->buffer)) * buffer_len);
a->buffer_len = buffer_len;
a->write_index = 0;
a->read_index = 0;
return a;
}
void write_c_KeyRingBuffer(struct KeyRingBuffer* a, int c)
{
int current_write_index;
if((a->write_index + 1) >= a->buffer_len) {
current_write_index = 0;
}
else {
current_write_index = a->write_index + 1;
}
a->buffer[current_write_index] = c; // 実際にデータをまだ書き込んでないので、インデックスは仮のものを使う。
a->write_index = current_write_index; // データが実際に書き込まれた後に、インデックスを増加させる。ここがポイント
}
int read_c_KeyRingBuffer(struct KeyRingBuffer* a)
{
if(a->read_index == a->write_index) {
return -1; // 読まなかったことを伝える、何らかのリターン値
}
// write_index と read_index が重なってない場合は、読む。
// 以下は write_c_KeyRingBuffer() の場合と同様の手順
int current_read_index;
if((a->read_index + 1) >= a->buffer_len) {
current_read_index = 0;
}
else {
current_read_index = a->read_index + 1;
}
int c = a->buffer[current_read_index];
a->read_index = current_read_index;
return c;
}
// <---------- class KeyRingBuffer ----------
// 0.1s単位 スリープ
void aaa_sleep(int a)
{
struct timespec req;
req.tv_sec = 0;
req.tv_nsec = (1000 * 1000 * 100) * a;
nanosleep(&req, NULL);
}
// Blike側を例えたスレッド
// ポイント:Blike() は、KeyRingBuffer へのアクセスに関して、read_ しか行っていない
void* Blike(void* a)
{
while(1) {
// 適当なタイミングで、キーリングからキーを読み込む
aaa_sleep(rand()%10);
int c = read_c_KeyRingBuffer((struct KeyRingBuffer*)a);
// バッファーに読むべきデータがあって、読み込めれば、その値を表示
if(c != -1) {
printf("Bliek [read] %d\n", c);
}
}
}
// Driver側を例えたスレッド
// ポイント:Driver() は、KeyRingBuffer へのアクセスに関して write_ しか行っていない
void* Driver(void* a)
{
static int c = 0;
while(1) {
// 適当なタイミングで、キーリングにキーを書き込む
aaa_sleep(rand()%10);
write_c_KeyRingBuffer((struct KeyRingBuffer*)a, c);
// いま書き込んだ値を表示
printf("Driver [write] %d\n", c);
c++; // 次に書き込むときの、新しい値
}
}
main()
{
struct KeyRingBuffer* a = new_KeyRingBuffer(123);
pthread_t blike_thread;
pthread_create(&blike_thread, NULL, Blike, (void*)a); // Blike() と Driver() 間での共有メモリとして a を捉える
pthread_t driver_thread;
pthread_create(&driver_thread, NULL, Driver, (void*)a);
pthread_join(blike_thread,NULL);
}