2

これは、最小限の例で私の問題を示す C++ コードです。

// uncomment the next line, to make it hang up:
//#define BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG //needed for nanosecond support of boost
#include <boost/thread.hpp>
void foo()
{
    while(true);
}
int main(int noParameters, char **parameterArray)
{
    boost::thread MyThread(&foo);
    if ( MyThread.timed_join( boost::posix_time::seconds(1) ) )
    {
        std::cout<<"\nDone!\n";
    }
    else
    {
        std::cerr<<"\nTimed out!\n";
    }
}

ナノ秒のサポートをオンにしない限り、すべてが期待どおりに機能しますが、boost::posix_time でナノ秒のサポートに必要な #define のコメントを外すとすぐに、プログラムは if ステートメントを通過しなくなります。 timed_join() の代わりに join() を呼び出したかのように。

これは、BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG がタイムスタンプの実際のデータ表現を単一の 64 ビット整数から 64+32 ビットに変更するために発生することがわかっています。多くのブースト機能はヘッダー内に完全に実装されていますが、スレッド メソッドは実装されていません。そのため、適切なオプションを使用して再度コンパイルしないと、新しいデータ形式に適応できません。コードは外部サーバーで実行することを意図しているため、独自のバージョンのブーストをコンパイルすることはオプションではなく、ナノ秒のサポートをオフにすることもありません。

したがって、私の質問は次のとおりです: 互換性のない 96 ビットの posix_time メソッドを使用せず、標準のブースト パッケージを変更せずに、値 (秒単位) を timed_join() に渡す方法はありますか?

ブースト1.46.1を搭載したUbuntu 12.04で実行しています。

4

1 に答える 1

1

残念ながら、あなたの問題は書かれているようにきれいに解決できるとは思いません。リンクしているライブラリはナノ秒のサポートなしでコンパイルされているため、ライブラリ バイナリに既にコンパイルされている部分に対してナノ秒のサポートを有効にすると、定義上、1 つの定義ルールに違反します。この場合、 への関数呼び出し全体で有効にしていますtimed_join

自明の解決策は、どちらをあきらめるのが苦痛でないかを決定することです: 独自のブーストを構築するか、ナノ秒時間を削除します。

完全に機能する場合と機能しない場合があるあまり明白でない「ハック」timed_joinは、スレッドオブジェクトと、int秒またはミリ秒などを表す独自のラッパーを作成することです。次に、この関数はソース ファイルに他に何も実装されておらず、コンパイルされたブースト バイナリを呼び出すという特定の目的のためにナノ秒時間を有効にしません。繰り返しになりますが、このような使用法を完全に分離しなければ、1 つの定義ルールに違反し、未定義の動作が発生することを強調したいと思います。

于 2013-02-22T19:50:05.783 に答える