minitalk
課題のまとめです
minitalkって何をするの?
->プロセス間通信(SIGNAL)を使ってサーバーとクライアントの比較的安全な通信を行い文字列を受け渡すこと
具体的に
serverというプログラムとclientというプログラムに分けてclientからserverにシグナルを送り、送ったシグナルの数で文字列を読み取りserver側のターミナルに表示させる
シグナルの送受信はkillとsignalの関数ですぐ出来るので割愛
文字列の送受信方法
asciiだと1文字は7ビットで1と0で表現できるので
SIGUSR1(以下S1)とSIGUSR2(以下S2)に1と0を割り振ってあげればserver側で戻すことができそう
・client側
文字列の一番左のビットが1であればS2、0であればS1に送る。それを右に1ビットずつずらしながら8回繰り返す
+1回はEOFを判断するため
・server側
受け取ったシグナルを奇数偶数で判断(S1が31でS2が32)し、それをchar型に右側にずらしながら足していく
7回(一文字が7ビットなので)シグナルを受け取ったらwriteでターミナルに書き出していく
文字列の最後には全て0が来るので文字アスキーが'\0'の時改行を出力して終了する
注意点
シグナル通信を行う際はシステムコール系の関数を使うこと
malloc・freeを使うときはシグナルハンドラ関数内で使用するとシグナルハンドラ内でfreeした場合ハンドラ関数作動中に割り込みが入ったときfreeされなかったり2重freeされたりするため避ける
使った関数
・kill
→kill(pid, SIGNAL)で渡したpidに任意のSIGNALを送りつけることができる
・signal
→signal(SIGNAL, 関数)で渡したSIGNALが来たら任意の関数に誘導できる
・pause
→pause()でSIGNALがくるまでそのプログラムを止めておくことができる
・usleep
→usleep(int)でint マイクロ秒元スレッドの動作を止めることができる
・write
→お馴染みのやつwrite(fd, 文字列, sizeof(文字列))fdに文字列をバイト数分書き込む
追記
・非同期処理におけるgetpidの返り値を格納する型などがあるのでそれを使うとより安全性が高まる
・staticや配列を使えばグローバル変数を使っての値の保持が必要なくなるかつunicode対応までできる
・sigaction関数を使えばclient側のpidを習得して相互に通信して終了を知らせることができる