2012-05-05 20 views
5

Soru: Kod yürütmenin yalnızca çok iş parçacıklı bir programda bir kerede bir iş parçacığında gerçekleşmesini garanti etmek mümkün mü? (Bu yaklaşır Ya da bir şey)C++ çoklu iş parçacıklı programında seri kod yürütme

Özellikle: Ben A, B, C ı M çalışmasına izin verilmelidir kim karar edebilmek istiyorum bir kontrolör (bir iplik) M ve konuları vardır. Başkaları yayınlanmıyor ise İdeal A, B ve C kendi iplik kendi kodu çalıştırmak istiyorum: iplik kontrol transferleri geri Neden M.

için (ya nihayet veya geçici olarak) tamamlandığında. Bu, her bir iş parçacığının, denetim denetleyicisini denetleyiciye geri verdiğinde bıraktıkları yerden başlayıp, durduklarında yönergelerini ve yığınlarını tutmasını sağlar.

Şu an yapıyorum: Bunu gerçekten yapabileceğim bir kod yazdım - ama beğenmedim. Sözde C'de

:

//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); 

nedeni

do{}while(lockval==0); 

gereklidir neden muteks kilitli değilken, A ve M hem devam edecektir. Bu kesmek, A'nın M kilitlemeden önce A'nın kilitlemeyeceğini ve A'nın kilidi tekrar ikinci kez tekrar alıp tekrar çalışacağını (sadece bir kez çalıştırılması) sağlar.

do-while

overkill gibi görünüyor, ama iş yok. Yani benim sorum, daha iyi bir yolu var mı? Win32 "CriticalSection" için

+0

Niçin A, B ve C iş parçacıklarının aynı anda çalışmasını istemiyorsunuz? Çözmeye çalıştığın problem nedir? Sorunu çözmek için neredeyse kesinlikle daha iyi bir yol var, ama bize sorunun ne olduğunu * söylemelisiniz *. –

+0

Bu bölüm beni şaşırtıyor: "Bu, her bir iş parçacığının, komut satırlarını ve bekletme sırasında yığınlarını tutmalarını sağlar". Bu mutekslerin amacı değil.İşletim sistemi (önleyici iplik modeli varsayılarak), her bir iş parçacığının yığınını korur ve CPU zamanını verdiği için kaydeder. – veefu

+1

@veefu - OP 'yeşil dişler' istiyor, AKA lifleri (sanırım). A, B ve C'nin hepsi kendi yığınlarını alırlar, ancak yalnızca bir tanesi bir seferde çalışabilir, çünkü yalnızca bir tane çekirdek iş parçacığı vardır. –

cevap

2

Windows'ta çalıştığınızı varsayarak, Fibers'a bakmayı deneyebilirsiniz. ("Pencere lifleri" http://developer.amd.com/Pages/1031200677.aspx örneğin Bkz ya da sadece google.)

Ben gerçekten değiş tokuş eden kavramlar arıyoruz şüpheli.

+0

Evet - 'thread' kullanıcısı AKA lifleri gibi geliyor. –

+0

Bu tam olarak neye ihtiyacım var gibi geliyor. Teşekkürler! – EggplantBonanza

+1

Eğer A, B ve C konuları iş parçacığı M'ye yine de geri dönüyorsa, neden sadece iş parçacığı ile birlikte uzaklaşıp sadece funcA fucnB ve funcC'yi iş parçacığı M? Elyaf soyutlaması gerçekten gerekli mi? – veefu

0

C++ kodunun linux ve pthread API kullanılarak kodlandığını farz ediyorum. İşte kod, çok sağlam değil, ama başlamak için iyi bir nokta. Umarım faydalıdır. İkili yürütmeyi yapmak için "g ++ test_controller_thread.cpp -preadread -o test_controller_thread" komutunu kullanın.

// 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; 
} 
İlgili konular