2

POSIX スレッドを使用して範囲内の完全数を計算する非常に非効率的なアルゴリズムを使用するプログラムを作成しようとしています。アルゴリズムを正しく機能させるために、ロックの概念を十分に理解できていないようです。完全数のリストを返したい。これをより適切に実装する方法について、誰かアドバイスをいただけますか?

具体的な質問: - 各完全数のインスタントを 1 つだけ出力するにはどうすればよいですか? - 値を出力するだけでなく、値を返すようにするにはどうすればよいですか?

ソース:

static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;

static void * threadFunc(void *arg) {

    int range, start, end;
    int i, s,  number, mod, divisor, temp, sum;

    s = pthread_mutex_lock(&mtx);   

    /* Takes in a string and pulls out the two integers */
    sscanf(arg,"%i-%i", &start, &end);
    printf("\nStart: %i\nEnd: %i\n", start, end);

    printf("\n");

    s = pthread_mutex_unlock(&mtx);

    for (number=start; number<=end; number++) { // loop through range of numbers                

        temp=0,sum=0;           
        // loops through divisors of a number and sums up whole divisors
        for (i=1; i<number; i++) {          
            //s = pthread_mutex_lock(&mtx);             
            mod = number % i;           
            //s = pthread_mutex_unlock(&mtx);           

            if (mod == 0){              
                s = pthread_mutex_lock(&mtx);               

                divisor = i; 
                sum = divisor + temp;
                temp = sum;

                s = pthread_mutex_unlock(&mtx);                     
            }                       
        }
        //if the sum of whole divisors is equal to the number, its perfect
        if (sum == number)  {           

            s = pthread_mutex_lock(&mtx);           

            printf("%i is a Perfect Number \n", sum);
            //return sum somehow;           

            s = pthread_mutex_unlock(&mtx);         
        }
    }

    return NULL;
}


int main(int argc, char *argv[]) {
    pthread_t tid[5];

    int prefect_number, i, s;

    char input[]="1-9999";

    for(i=0; i < 5; ++i) {
        pthread_create(&tid[i], NULL, &threadFunc, input);
        print_thread_info();
    }
    /* Wait for the perfect number thread to complete, then get result. */  
    for(i=0; i < 5; ++i)
        pthread_join(tid[i],NULL);

    return 0;   
}
4

1 に答える 1

0

別のスレッドから変更される可能性のあるデータ構造(グローバル変数など)またはリソース(ターミナルなど)にアクセスする場合にのみ、ミューテックスをロックする必要があります。

  • シングルスレッドにローカルな変数にアクセスするためにミューテックスをロックする必要はありません
  • 別のスレッドによって変更されることのないグローバル変数を読み取るためにミューテックスをロックする必要はありません

したがって、あなたの場合、ミューテックスの単一のユースケースは、複数のprintf()が出力を混同する可能性を防ぐことです。

また、すべてのスレッドが同じ範囲を探索するのは無意味です。おそらく、それぞれ異なる範囲(0-1999、2000-2999 ... 8000-9999)を探索する5つのスレッドが必要ですか?

pthread_join()は、スレッドの終了値(returnまたはpthread_exit()に渡す値)を返します。複数の値を返したい場合は、数値のリンクリストを保持するグローバル変数を作成することをお勧めします(異なるスレッドがそれに書き込む必要があるため、最終的にミューテックスが必要になります)

于 2012-12-31T14:51:38.047 に答える