1

できる限りグーグルで検索しましたが、これに対する良い答えが見つかりませんでした。

localtime_r は、システム時刻を取得するためのスレッドセーフな関数であると想定されています。しかし、Valgrind --tool=drd を使用してアプリケーションをチェックすると、この関数にデータ競合状態があることが一貫してわかります。一般的な検索結果は嘘をついているのですか、それとも単に何かを見逃しているだけですか? 各 localtime_r 呼び出しをミューテックスで囲むのは効率的ではないようです。特に、最初からスレッドセーフであると想定されている場合はなおさらです。これが私がそれを使用している方法です:

timeval handlerTime;
gettimeofday(&handlerTime,NULL);

tm handlerTm;
localtime_r(&handlerTime.tv_sec,&handlerTm);

何か案は?

4

2 に答える 2

2

ドキュメントに再入可能(したがってスレッドセーフ) であると記載されている場合は、そうです。

コード (あなたのコードではない) にバグがあり、関数が実際にはスレッドセーフでなかった場合、(別の関数を使用しない限り) それについてできることはあまりなく、これを修正するのはあなた次第ではありません。コード内: 関数は、ドキュメントに記載されているとおりに動作する必要があります。

ただし、 によって得られる結果には注意が必要valgrindです。これは素晴らしいツールで、私は頻繁に使用しています。しかし、時々、それは間違っています。そして、競合状態を検出するのと同じくらい難しいことについては、それが何を言っているのかについてさらに注意を払うでしょう. 特に何十年も使われている標準機能について。

ここでの私のアドバイスは次のとおりです。無視してください。問題が発生し、localtime_r()その責任があると思われる場合は、適切なメーリング リストに書き込み、問題を報告するか、別の機能を使用してください。

その間、あなたは大丈夫なはずです。

于 2010-06-17T09:06:06.577 に答える
1

マンページから:

ctime_r()、localtime_r()、および tzset() 関数は、ユーザー定義関数が変数 timezone、altzone、daylight、および tzname のいずれかを直接変更しない限り、マルチスレッド アプリケーションで MT セーフです。これら 4 つの変数へのアクセスは MT セーフではありません。これらは、MT セーフな方法で tzset() 関数によって変更されます。mktime()、localtime_r()、および ctime_r() 関数は、tzset() を呼び出します。

コード内でこれらの変数に直接アクセスしていない限り、valgrind が誤検知を報告している可能性があります。関数内で競合状態が存在すると考えられる場所について、さらに詳細を教えてくれますか?

valgrind でさらに確証がない限り、追加のロックなしで引き続き使用しても安全だと思います。

于 2010-06-21T19:01:13.343 に答える