はじめに
ターゲット: 私と同じくC言語初心者
大学の課題にC言語でスロットマシンを実装せよとの課題が出たので, これはキーボード入力を受け付けながらスロットのリールが動くのを出力しないといけないのではと思ってちょっと調べてみました.
実行環境
OS: Ubuntu 20.04.3 LTS(WSL)
コンパイラ: gcc version 9.3.0
どうやって実装するか
pthreadを使います(直球)
pthreadはPOSIX threadの略で, UNIX系OSでスレッドプログラミングをする際に使用されるらしいです.
threadをいくつか作ってそれを同時に実行させるような処理を行います.
pthreadの使い方
pthreadは, 次のような感じで書きます. これがC言語にしては割と便利で, そんなに難しくないです.
以下のsample.cはENTERキーを押した回数を出力しつつ, そのENTERキー入力も同時に行うプログラムです.
sample.c
# include<pthread.h>
# include<stdio.h>
# include<stdlib.h>
# include<unistd.h> // for usleep func
# define NUM_KBHITS_DONE 5
# define ASCII_ENTER 10
# define WAIT_MILSEC 1000*1000 //thread2のループ時に1秒待つ
typedef struct{
int isHit; //0->false, else->true
int num_kbHits;
int hogehoge;
}ArgForStruct;
ArgForStruct *createStruct(void);
void* thread1(void *);
void* thread2(void *); //引数は1つしか渡せない. 2つ以上渡したいときは構造体を使います.
int main(){
ArgForStruct *myStruct = createStruct();
//スレッド生成
pthread_t inputThread;
pthread_t showingThread;
//スレッド開始
pthread_create(&inputThread, NULL, thread1, myStruct); //4つ目の引数がスレッドへの
pthread_create(&showingThread, NULL, thread2, myStruct);//引数になります
//スレッド終了待ち
pthread_join(inputThread, NULL);
pthread_join(showingThread, NULL);
return 0;
}
ArgForStruct *createStruct(){
ArgForStruct *myStruct = malloc(sizeof(ArgForStruct));
myStruct->num_kbHits = 0;
myStruct->hogehoge = 123;
return myStruct;
}
//wait input
void* thread1(void *argStruct){
ArgForStruct *myStruct = (ArgForStruct *)argStruct; //cast
for(;;){
if(myStruct->num_kbHits == NUM_KBHITS_DONE){
myStruct->isHit = 1;
pthread_exit(NULL); //スレッド終了
}
//キーボード入力待ち
int temp = getchar();
if(temp == ASCII_ENTER){
printf("ENTER HIT\n");
myStruct->num_kbHits++;
}
}
}
//showing argStruct->num_kbHits
void* thread2(void *argStruct){
ArgForStruct *myStruct = (ArgForStruct *)argStruct; //cast
for(;;){
printf("current kbHits: %d\n", myStruct->num_kbHits);
usleep(WAIT_MILSEC); //1秒待つ
//スレッド1で構造体のisHitが書き換えられたらスレッドを抜ける
if(myStruct->isHit != 0){
printf("keyboard Hits Done!: %d\n", myStruct->num_kbHits);
pthread_exit(NULL);
}
}
}
実行結果
コンパイルは, オプションに "-pthread" をつける必要があります.
$gcc -pthread main.c
$./a.out
current kbHits: 0
current kbHits: 0
current kbHits: 0
current kbHits: 0
ENTER HIT
current kbHits: 1
current kbHits: 1
current kbHits: 1
ENTER HIT
ENTER HIT
current kbHits: 3
current kbHits: 3
current kbHits: 3
ENTER HIT
current kbHits: 4
current kbHits: 4
ENTER HIT
keyboard Hits Done!: 5
あとがき
面白かった(小並感)
(追記) 講義はプロセス(forkとか)使って解説されててちょっと悲しかった