Running serial code in a multithreaded C ++ program

Question: Is it possible to guarantee code execution in only one thread in a multithreaded program? (Or something that comes close to this)

In particular: I have a controller M (which is a thread) and threads A, B, C. I would like M to be able to decide who is allowed to work. When the flow is completed (permanently or temporarily), control transfers back to M.

Why: Ideally, I want A, B, and C to execute their code in their thread, while others do not start. This will allow each thread to keep a pointer and a stack of instructions during a pause, starting from where they left off when the controller returns them.

What I'm doing now: I wrote code that can really do this, but I don't like it.

In pseudo-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);

Reason for which

 do{}while(lockval==0);

when the mutex is unlocked, both A and M must continue. This hack ensures that A does not unlock the mutex before M can lock it again, so that A will brake the lock again and restart (it should only start once).

Still seems redundant, but does the job. So my question is: is there a better way?

+5
source share
3 answers

Assuming you are running Windows, take a look at Fibers. (See, for example, http://developer.amd.com/Pages/1031200677.aspx or simply Google's fiberglass.)

, .

+2

"CriticalSection" Win32. ++ 11 "lock_guard".

Boost?

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

do{}while(lockval==0);

.

+1

, ++ linux pthread API. , , . , . "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;
}
0

All Articles