質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Q&A

解決済

2回答

5643閲覧

マルチスレッドプログラム(Linux)によるシリアル通信受信 [ C言語 ]

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

0グッド

0クリップ

投稿2016/10/26 11:43

編集2016/10/27 12:28

前回、マルチスレッドプログラムについて説明した者です。

シグナルにおいて非同期シグナルセーフな関数を用いずに処理をおこなっていたため、デッドロック等の可能性を踏まえプログラムを改良しております。

シグナルではなくsigwait() を用いて、同期的なシグナル待機に書き換えております。sigwait()を使用することで、非同期シグナルセーフな関数に限定せずにプログラムを書くことができるため、これを利用しています。
プログラムは全てのスレッドで受信に関するシグナルをブロックし、sigwait()の返答により、受信を開始しています。

無事にsigwait()からの信号により受信を確認できたのですが、
連続で受信を行っていると途中で取りこぼしが発生します。
この取りこぼしをなくすような工夫がございましたら、ご教示お願い致します。またプログラムの不完全な点の指摘もあわせてしていただけましたら幸いです。

C

1 2 sigset_t ss; 3 4 <> 5 6 sigemptyset( &ss ); 7 ret = sigaddset( &ss, SIGIO ); 8 if( ret != 0 ){ 9 perror( "sigaddset" ); 10 return -1; 11 } 12 13 ret = pthread_sigmask( SIG_BLOCK, &ss, NULL ); 14 if( ret != 0 ){ 15 perror( "pthread_sigmask" ); 16 return -1; 17 } 18

C

1sigwait() を処理するスレッド 2 3void* wwait(){ 4 5 while(1){ 6 printf( "sigwait...\n" ); 7 8 if( sigwait( &ss, &signo ) == 0 ){ 9 10 pthread_mutex_lock( &mutex0 ); 11 condition = 1; 12 pthread_cond_signal( &cond0 ); 13 pthread_mutex_unlock( &mutex0 ); 14 15 } 16 } 17 18 pthread_exit(0); 19}

C

1受信処理をおこなうスレッド 2 3// receive thread 4void* thread0(){ 5 6 pthread_mutex_init( &mutex0, NULL ); 7 pthread_cond_init( &cond0, NULL ); 8 9 memset( &action, 0, sizeof(action) ); 10 memset( &evp, 0, sizeof(evp) ); 11 12 while(1){ 13 printf( "receive...\n" ); 14 15 pthread_mutex_lock( &mutex0 ); 16 17 while( !condition ){ 18 pthread_cond_wait( &cond0, &mutex0 ); 19 } 20 21 condition = 0; 22 23 memset( buffer, '\0', sizeof(buffer) ); 24 k = 0; 25 26 k = read( fd[0], buffer, sizeof(buffer) ); 27 printf( "receive char : %d \n" , k ); 28 29 pthread_mutex_unlock( &mutex0 ); 30 31 } 32 33 pthread_exit(0); 34} 35

ikedas 様

追記致します.
シリアルポート通信速度は115200bps
また, このプログラムはlinuxの動くマイコンで動作させ,対向とはRS232Cを使用してモデムと接続しデータ通信をおこないます.
しかし現在はまだデバッグ段階のため, デスクトップとノートパソコンをUSB-シリアル, クロスケーブルで接続し, ノートパソコンでは一定周期でシリアル通信で送信するプログラムを動作させています.

また加えてお答え頂ければ幸いですが、タイマーハンドラでもシグナルハンドラと同様に、シグナルセーフな関数し使用することができないのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ikedas

2016/10/26 13:58

参考まで、差し支えなければお教えいただきたいのですが、シリアルポートの通信速度は何bpsでしょうか。また、対向との接続の物理的な構成 (機器など) はどんなものでしょうか。
guest

回答2

0

ベストアンサー

これが原因とは限らないのですが。

前回のご質問を見ると、ハードウェアフロー制御 (CRTSCTS) を無効にしておられるようです。DTE速度が上記の通りなら、アナログモデムのDCE速度を上回ることは確実なので、必要ではないかと思います。

なお、現在はクロスケーブルで試験されているとのことですが、制御線も結線されているものを使わないと、特に通信速度を上げたときにうまくいかないかもしれません。クロスケーブル (ヌルモデムケーブル) の中には、制御線を結線しなかったりコネクタ内で短絡したりしているものもあります。

投稿2016/10/27 08:50

ikedas

総合スコア4227

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/10/31 02:04

ご回答ありがとうございます。 DTE速度はモデム側で推奨されている値を設定致しましたが、再度制御線について確認致します。
guest

0

プログラム上あり得るとしたら、下記のようになっているとかですかね。
たぶん問題ないような気がしますが。

sigwait() ここで、シグナルリードすると”A”だけど pthread_cond_signal( &cond0 )で受信スレッドを起こす ここでは、シグナルの書き込みが発生していて”B" 受信スレッドがシリアルリードすると”B"

メッセージキューか何かを使って、
シグナル発生時に取りこぼしがないか確認してみてください。

sigwait()直後に
シグナルリードしてその内容をリードし、バッファーに保存。
受信スレッド側で保存した内容をリードする。

投稿2016/10/26 14:15

hidetzu

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hidetzu

2016/10/27 12:57

前回の質問と同じ設定であるとしますと ikedasさんの回答に記載されている内容が一番しっくりくるかと思います。 CRTSCTSを有効にして実験できるのであればそちらで実験してみるほうがよいかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問