1

マルチプロデューサーとマルチクライアント間の通信に共有メモリを備えたセマフォを使用しています。私のシステムには、「格納されたセマフォ」と「処理されたセマフォ」の 2 種類のセマフォがあります。

システムは次のように実行されます。プロデューサは継続的にデータを共有メモリに入れ、格納されたセマフォの値を増やします。コンシューマはループ内にあり、そのような格納されたセマフォを待っています。コンシューマは、プロデューサからデータを受け取った後、そのようなデータを処理し、処理されたセマフォの値を増やします。プロデューサーは、「処理されたセマフォ」を待って結果を取得します。

生産者コード:

for(int i =0;i<nloop;i++){
    usleep(100);
    strcpy(shared_mem[i], "data for processing");
    sem_post(&shared_mem[i].stored_semaphored);
    if(sem_timedwait(&msg_ptr->processed_semaphore,&ts)==-1){ //waiting for result 
        if(errno == ETIMEDOUT){
        }
        break;
    }else{
       //success
    }

}

消費者コード:

for (int j = 0; j < MAX_MESSAGE; j++) {
if (sem_trywait(&(shm_ptr->messages[j].stored_semaphore)) == -1) { 
    if (errno == EAGAIN) {
    } else {
            //success ==> process data
            //post result back on the shared memory, and increase                         
            //the processed semahore
        strcpy(shared_mem[j].output, "Processed data");
        sem_post(&(shared_mem[j].processed_semaphore)); 
    }
}
}//for loop over MAX_MESSAGE

私の問題は、プロデューサーからのデータがない場合、この for ループが継続的に実行されるため、消費者コードの for ループがほぼ 100% の CPU を浪費していることです。

私の質問は、CPU 時間を無駄にしない、一連のセマフォ (SELECT、POLL、または EPOLL による待機メカニズムに似ている可能性があります) を待機する他の方法があるということです。

あなたの答えを見てください。本当にありがとう!

4

1 に答える 1

1

私の知る限り、一連のセマフォを待機する方法はありません。これは、すべてのアクセスを 1 つのセマフォに集中させる必要があることを意味します。セマフォのセットをループしているので、それらをまとめて 1 つのオブジェクトにすることができます。そのコンシューマは、セマフォのいずれかがいつ通知されたかを知る必要があるためsem_post、新しいセマフォで追加を使用して、セマフォのセットが変更されたことを通知します。

プロデューサー コードは次のようになります。

....
sem_post(&shared_mem[i].stored_semaphored);
sem_post(&list_changed_semaphore); /* Wake the consumer. */
....

そして消費者:

/* Block until a consumer has indicated that it has changed the semaphore list */
if (!sem_wait(&list_changed_semaphore)) {
    /* At least one producer has signalled a change. */
    for (int j = 0; j < MAX_MESSAGE; j++) {
        if (sem_trywait(&(shm_ptr->messages[j].stored_semaphore)) == -1) { 
        }
    }
}

セマフォを使用する代わりに、条件変数を使用して、セマフォのセット内の何かが変更されたことを通知list_changed_semaphoreできます。pthread_cond_tは、ここlist_changed_semaphoreに示す例のようにカウンターである必要はありません。プロデューサーがリストを変更したことを示す単一ビットのみが必要です。

于 2013-03-27T06:03:00.117 に答える