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

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

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

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

マルチスレッド

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

Q&A

解決済

6回答

9535閲覧

C言語でマルチスレッドでのファイル出力

rockn26

総合スコア16

C

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

マルチスレッド

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

0グッド

0クリップ

投稿2020/07/01 17:49

編集2020/07/11 19:52

C言語でのマルチスレッドでのログファイル出力したいと考えています。

以下の方法にて、試みてみましたが、ログを確認するとマルチスレッドの為か、グチャグチャになってしまいます。
排他制御等が必要なのでしょうか?
詳しい方、教示願います。

・7/12 追記
返答遅くなりすいません。

ファイルがグチャグチャというのは、其々のタスクから出力した文字列が混ざったような出力結果ということです。
正確にはマルチスレッドというより、マルチタスクです。
[プラットフォーム] vxWorks

#include <stdio.h> #include <sys/types.h> FILE *fp; char filename[] = "sample.log"; void log(void) { fprintf(fp, "%s : tid => %d\n", __func__, gettid());   /*7/12補足漏れ追記 */ fflush(fp); } int main(void) { /* ファイルオープン */ if ((fp = fopen(filename, "a+")) == NULL) { fprintf(stderr, "ファイルのオープンに失敗しました.\n"); return EXIT_FAILURE; } /*途中簡略 複数スレッド起動して、各スレッドから上記log関数をコールする*/ /* ファイルクローズ */ fclose(fp); }

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

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

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

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

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

dodox86

2020/07/01 18:55

> グチャグチャになってしまいます。排他制御等が必要なのでしょうか? どのようにグチャグチャになってしまうのでしょうか。一般的には排他制御が必要です。Cランタイムライブラリも、スレッドセーフ、マルチスレッド対応版を使わなければならない場合もあります。試した動作環境OS、C言語環境を明示し、コード中の「途中簡略」とある部分を明らかにしないと正確な回答は望めないと思います。
episteme

2020/07/01 23:37

”グチャグチャ"の説明を求む。 複数のスレッドが関数:log()を呼ぶとファイル"sample.log"の中身が崩れていると推測されるが。 > 排他制御等が必要なのでしょうか? やってみるといい。
rockn26

2020/07/11 20:02

返答遅くなりすいません。 >複数のスレッドが関数:log()を呼ぶとファイル"sample.log"の中身が崩れている おっしゃる通りです。
guest

回答6

0

もし POSIX環境 ( pthread ) を使っていれば、fprintf もスレッドセーフのはずで、1回1回の呼び出しの内容(この場合は「行」)が混ざるということはないはずです。
が、ソースからは「何のマルチスレッド環境なのか」分からないので、なんとも言えません。

環境および、どういう意味での「ぐちゃぐちゃ」か明記してください。

なお、POSIXの場合、複数の出力をまとめたい ( 例えば fprintf 3回の呼び出しの間に割り込まれたくない ) ということであれば、stdio には flockfile, funlockfile という、ストリーム毎の排他制御が用意されています。
※使わなくても、1回1回の呼び出しは混ざらない

他のリソースもまとめて排他制御するなら pthread_mutex系の関数を使うのも良いと思いますが、I/Oだけの話ならこれで十分かと思います。

投稿2020/07/02 17:44

編集2020/07/02 17:54
angel_p_57

総合スコア1672

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

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

rockn26

2020/07/11 19:59

返答遅くなりすいません。回答ありがとうございます。 Linux系OSです。 mutex使用する方向で考えます。 flockfile, funlockfileは勉強したいと思います。
guest

0

ベストアンサー

c

1#include <pthread.h> 2 3pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 4 5void log(){ 6 pthread_mutex_lock(&mtx); 7 8 //fprintf(fp, "%s : tid => %d\n", __func__, gettid()); 9 printf("log"); 10 11 pthread_mutex_unlock(&mtx); 12} 13 14// プログラム終了前に呼ぶ 15void log_finalize() { 16 pthread_mutex_destroy(&mtx); 17}

投稿2020/07/02 14:54

maai

総合スコア463

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

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

rockn26

2020/07/11 19:58

返答遅くなりすいません。回答ありがとうございます。 この方法試したところ、今のところ問題も無く動作するようになりました。
guest

0

こんにちは。

もともとC言語はマルチスレッドを想定せずに設計されています。
今更、C言語の標準ライブラリを今更マルチスレッド対応すると既存のプログラムが大量に壊れるので、残念ながらスレッド・セーフではないケースが少なくありません。

そのような場合は、当該処理をスレッド・セーフになるようラップする等の対処が必要です。
ご提示の処理の場合、log()関数が複数のスレッドから同時に呼ばれても、fprintf()呼び出しが同時に複数回呼ばれないよう制限することで対処できると思います。

そのような「保護」にはmutexがよく用いられます。
mutexをlockできるのは1つだけです。複数のスレッドがlockしようとすると1つだけlockに成功してlock関数から戻ってきます。残りのスレッドは、通常はlockしたスレッドunlockするまでlock関数から戻ってきません。もちろんunlockされた時にlockに成功するスレッドは1つだけです。

既にマルチスレッド対応されているということは、そのライブラリ、もしくは、APIセットの中にmutexが用意されている筈です。探されてみて下さい。

投稿2020/07/02 02:42

Chironian

総合スコア23272

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

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

rockn26

2020/07/11 19:56

返答遅くなりすいません。回答ありがとうございます。 Linux系OSです。 mutex使用する方向で考えます。
guest

0

ファイルの書き込み開始・終了で排他処理が必要です。
C++では std::mutex が標準で用意されていますが、C++不可なら、WindowsならEnterCriticalSection、LeaveCriticalSection等のAPIを使用して同期を行ってください。(他OSだと良く分かりません)
C++ マルチスレッドの排他処理
スレッド間の排他制御(クリティカルセクション)

投稿2020/07/02 00:03

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

rockn26

2020/07/11 19:55

返答遅くなりすいません。回答ありがとうございます。 Linux系OSです。 排他制御するしかないようですね。
guest

0

どこがどのように、混ざるのかによります。
大変お手数ですが、ハイパースレッド系のタスキングの処理に問題が出ている可能性があるので、カーネルパッチが必要な問題かもしれません。
お手数ですが、パイパースレッドコア SMT系コアに関してはカーネルにパッチが必要な場合がありますので製造メーカーの方にお問い合わせください。ただしその場合でも文字は混ざります。文字化けレベルで混ざっている場合はメーカーによるパッチが必要です。

投稿2020/07/20 04:37

kokorohamoe

総合スコア190

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

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

0

さまざまなアプローチがあります。ソートにマージソート、バブルソート等があるのと同じで、一長一短いろいろなアルゴリズムがある折るので排他制御があるアルゴリズム、無いアルゴリズムいろいろあります。ただ、排他制御をするアルゴリズムのほうが簡単で覚えやすく教えやすいのでまずはそちらから初めてみてはいかがでしょうか?

投稿2020/07/01 22:12

kokorohamoe

総合スコア190

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

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

episteme

2020/07/04 01:50

低評価。回答になっていない。 「排他制御等が必要なのでしょうか?」に答えていない。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問