5

質問:マルチスレッドプログラムでは、コードの実行が一度に1つのスレッドでのみ発生することを保証できますか?(またはこれに近いもの)

具体的には、コントローラーM(スレッド)とスレッドA、B、Cがあります。Mに、誰に実行を許可するかを決定できるようにしたいと思います。スレッドが(最終的または一時的に)終了すると、制御はMに戻ります。

理由:理想的には、A、B、Cが、他のスレッドが実行されていないときに、独自のスレッドでコードを実行するようにします。これにより、各スレッドは、一時停止している間、命令ポインターとスタックを保持し、コントローラーが制御を戻したときに中断したところから再開できます。

私が今していること:私は実際にこれを行うことができるいくつかのコードを書きました-しかし私はそれが好きではありません。

疑似Cの場合:

//Controller M
//do some stuff
UnlockMutex(mutex);
do{}while(lockval==0);
LockMutex(mutex);
//continue with other stuff


//Thread A
//The controller currently has the mutex - will release it at UnlockMutex
LockMutex(mutex); 
lockval=1;
//do stuff
UnlockMutex(mutex);

理由

 do{}while(lockval==0);

必要なのは、ミューテックスのロックが解除されたときに、AとMの両方が続行することです。このハックにより、Mがミューテックスを再度ロックする前にAがミューテックスのロックを解除しないようにし、Aがもう一度ロックを取得して再度実行できるようにします(1回だけ実行する必要があります)。

do-whileはやり過ぎのように見えますが、仕事をします。だから私の質問は、もっと良い方法はありますか?

4

3 に答える 3

2

Windowsで実行していると仮定すると、Fibersを調べてみることができます。(たとえば、http: //developer.amd.com/Pages/1031200677.aspxまたは単にグーグルの「Windowsファイバー」を参照してください。)

あなたは本当にコルーチンを探しているのではないかと思います。

于 2012-05-05T13:54:57.243 に答える
1

Win32で「CriticalSection」を確認してください。C ++ 11は、「lock_guard」という別の用語を使用します。

Boostでクリティカルセクションを作成するにはどうすればよいですか?

http://en.cppreference.com/w/cpp/thread/lock_guard

あなたのコード

do{}while(lockval==0);

CPUパフォーマンスを使い果たします。

于 2012-05-05T13:40:10.713 に答える
0

Linuxでc++をコーディングし、pthreadAPIを使用していると思います。これがコードです。それほど堅牢ではありませんが、開始するのに適したポイントです。お役に立てば幸いです。「g++test_controller_thread.cpp -pthread -o test_controller_thread」を使用して、バイナリをエグゼクティブにします。

// 3 threads, one for controller, the other two for worker1 and worker2.
// Only one thread can proceed at any time.
// We use one pthread_mutex_t and two pthread_cond_t to guarantee this.
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>

static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_controller_cond = PTHREAD_COND_INITIALIZER;
static pthread_cond_t g_worker_cond = PTHREAD_COND_INITIALIZER;

void* controller_func(void *arg) {
    printf("entering the controller thread. \n");
    // limit the max time the controller can run
    int max_run_time = 5;
    int run_time = 0;
    pthread_mutex_lock(&g_mutex);
    while (run_time++ < max_run_time) {
        printf("controller is waitting.\n");
        pthread_cond_wait(&g_controller_cond, &g_mutex);
        printf("controller is woken up.\n");
        pthread_cond_signal(&g_worker_cond);
        printf("signal worker to wake up.\n");
    }
    pthread_mutex_unlock(&g_mutex);
}

void* worker_func(void *arg) {
    int work_id = *(int*)arg;
    printf("worker %d start.\n", work_id);
    pthread_mutex_lock(&g_mutex);
    while (1) {
        printf("worker %d is waitting for controller.\n", work_id);
        pthread_cond_wait(&g_worker_cond, &g_mutex);
        printf("worker %d is working.\n", work_id);
        pthread_cond_signal(&g_controller_cond);
        printf("worker %d signal the controller.\n", work_id);
    }
    pthread_mutex_unlock(&g_mutex);
}

int main() {
    pthread_t controller_thread, worker_thread_1, worker_thread_2;
    int worker_id_1 = 1;
    int worker_id_2 = 2;
    pthread_create(&controller_thread, NULL, controller_func, NULL);
    pthread_create(&worker_thread_1, NULL, worker_func, &worker_id_1);
    pthread_create(&worker_thread_2, NULL, worker_func, &worker_id_2);

    sleep(1);
    printf("\nsignal the controller to start all the process.\n\n");
    pthread_cond_signal(&g_controller_cond);

    pthread_join(controller_thread, NULL);
    pthread_cancel(worker_thread_1);
    pthread_cancel(worker_thread_2);

    return 0;
}
于 2012-05-06T01:26:58.533 に答える