2017-10-23 10 views
0

私は、x^2 + 1の積分をPOSIX Cコードとして計算するコードを書いています。半分の部分を再帰的に切断しています。再帰POSIXスレッドコードの競合状態?

私は知っている、私はライブラリを使用することができます、それは単なる研究のためです。


E1とE2は、このように、直接のパラメータとの統合を呼び出す前に、私の主な機能に初期化されます:私が、

float e1, e2; 

float f(float x) 
{ 
    return pow(x, 2) + 1; 
} 

float f1(float x) 
{ 
    return 2 * x; 
} 

typedef struct integrateArgs 
{ 
    float a; 
    float b; 
    float result; 
} integrateArgs; 

float integrate(float a, float b); 
void* integrateAsThread(void* args) 
{ 
    integrateArgs* myArgs = (integrateArgs*)args; 
    myArgs->result = integrate(myArgs->a, myArgs->b); 
    return NULL; 
} 

float integrate(float a, float b) 
{ 
    float diff = b - a; 
    if(a < 0 || a >= b || diff > 2 || e1 <= 0 || e2 <= 0) 
    { 
     return -1; 
    } 

    float x1 = (a + b)/2; 
    float x2 = f(x1); 
    if((f1(x1)/x2) > e1 && diff > e2) 
    { 
     float half = diff/2; 
     float newCenter = a + half; 

     integrateArgs rightPart = { .a = newCenter, .b = b }; 

     pthread_t thread; 
     pthread_create(&thread, NULL, integrateAsThread, (void*)&rightPart); 
     float left = integrate(a, newCenter); 
     pthread_join(thread, NULL); 

     return left + rightPart.result; 
    } 
    else 
    { 
     return diff * x2; 
    } 
} 

e1 = 10E-2; 
e2 = 2E-4; 
integrate(1.0, 2.0) 

コードは次のようになりますどこに競争状態があるように見えるかわからない。統合メソッドを次のように変更すると、実際には並列化が削除されますが、これは正常に機能します。最初のバージョンを使用すると、実行ごとに結果が異なります。

私は間違って何をしましたか?

+0

問題は表示されません。実行可能にするために欠けているビットを追加してください。 – ikegami

答えて

2

戻り値pthread_createをチェックしません。コードでスレッドが多数作成され、オペレーティングシステムの制限を超え、一部のサブタスクが実行されず、結果が不正になる可能性があります。

+0

あなたは正しいです。実際には何回かエラーコードとして35を返しました。 [Linuxシステムエラー](http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Errors/unix_system_errors.html)に基づいて、これは "リソースデッドロックが発生する"ことを意味します。私はそのエラーを処理したので、動作します。ありがとうございました! –