func1 と func2 の 2 つの関数を接続するコードがあります。両方の機能の役割は同じです。ディレクトリを継続的に読み取り続け、それぞれのログ ファイルに存在するファイルの名前を書き込みます。どちらの関数も、ログを書き込むために共通のログ関数を参照しています。コードで導入スレッドを使用して、両方が並行して実行され続けるようにしたいのですが、両方が同時にログ機能にアクセスしないようにします。それを達成する方法は?
6 に答える
これはミューテックスを必要とする典型的なケースです。
void WriteToLog(const char *msg)
{
acquire(mutex);
logfile << msg << endl;
release(mutex);
}
ミューテックスはシステム固有であるため、上記のコードはシステムに「コピーして貼り付ける」pthread_mutex
ことはできませんpthreads
。C++11 には独自のミューテックスとスレッド機能があり、Windows には別のバリアントがあります。
Sajal のコメントから:
pthread_create(&thread1, NULL, start_opca, &opca); を試しました。pthread_join(スレッド1、NULL); pthread_create(&thread2, NULL, start_ggca, &ggca); pthread_join(スレッド2、NULL);
しかし、これの問題は、次のスレッドを開始する前に、1 つのスレッドが終了するまで待機することです。私はそれをしたくありません。
join 関数は、join を呼び出したスレッドが終了するまで、呼び出しスレッドをブロックします。あなたの場合、2番目のスレッドを作成する前に最初のスレッドで join を呼び出すと、2番目のスレッドが始まる前に最初のスレッドが終了することが保証されます。
最初に 2 つのスレッドを作成してから、両方を結合する必要があります (作成物を散在させて両方を結合するのではなく)。
さらに、ログへのアクセスは、両方の共通コード (ロギング関数、ロギング クラスなど) に抽出する必要があります。抽出されたコード内では、ログ アクセスはミューテックスを使用して保護する必要があります。
(部分的に) c++11 をサポートする実装がある場合、これには std::thread と std::mutex を使用する必要があります。それ以外の場合は、boost::thread を使用する必要があります。どちらにもアクセスできない場合は、Linux で pthreads を使用してください。
両方のスレッドが I/O からの読み取り/書き込み (dirs の読み取りとログ ファイルの書き込み) を行うため、マルチスレッドは必要ありません。すべての I/O アクセスが下位レベルでキューに入れられるため、タスクを並列化しても速度は向上しません。
あなたの別の質問は存在しません。最初の pthread_join でメイン スレッドがサスペンドされますが、2 番目のスレッドが実行されないわけではありません。実際には、2 番目のスレッドは pthread_create(thread1) から始まります。
そして実際に pthread_mutex はあなたのプログラムのシリアルを引き起こします。
Linux では、 pthreadsを使用する必要があります。
この C 言語のコードがヒントになるかもしれません。質問に答えるには: pthread でミューテックスを使用して、同時に 1 つのスレッドのみがログ ファイルにアクセスできるようにする必要があります。
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t LogLock = PTHREAD_MUTEX_INITIALIZER;
char* LogFileName= "test.log";
void* func_tid0( void* a) {
int i;
for(i=0; i < 50; i++ ) {
pthread_mutex_lock(&LogLock);
fprintf((FILE*)a, "write to log by thread0:%d\n", i);
pthread_mutex_unlock(&LogLock);
}
}
void* func_tid1(void* a) {
int i;
for(i=0; i < 50; i++ ) {
pthread_mutex_lock(&LogLock);
fprintf((FILE*)a, "write to log by thread1:%d\n", i);
pthread_mutex_unlock(&LogLock);
}
}
int main() {
pthread_t tid0, tid1;
FILE* fp=fopen(LogFileName, "wb+");
pthread_create(&tid0, NULL, func_tid0, (void*) fp );
pthread_create(&tid1, NULL, func_tid1, (void*) fp );
void* ret;
pthread_join(tid0, &ret);
pthread_join(tid1, &ret);
}