2016-04-14 15 views
3

Genel değişkenini güncelleyen N iş parçacığı oluşturan bir C pthread programı var. Main ayrıca, tüm bu güncelleme işlerinde pthread_join'i bitirmelerini beklemek için çağırır. Ayrıca, genel değişkenin belirli sayıların üstüne veya altına gidip gitmediğini kontrol etmek için pthread durum değişkenlerini kullanan 2 gözlemci iş parçacığım var ve eğer öyleyse, tüm güncelleştirme iş parçacıklarını ve diğer izleyici dizisini öldürüyor. Ancak, bu son bölümle ilgili sorun yaşıyorum ... diğer konuları da çözüyorum. Programım yapması gereken şeyi yapıyor ama asla tamamlamıyor ... sadece sıkışıyor. Her izleyici iş parçacığının sonunda çıkış (0) çağrısı işe yarıyor, ama bu bir çözümün tembelliği gibi hissediyorum, gerçekten başka bir iş parçacığının nasıl diğer bir iş parçacığını öldürmeyi ve ana öğeye dönmeyi öğrenmek istiyorum.Pthreads ile Konuları Killing - C

#include <pthread.h> 
#include <time.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <assert.h> 

void *update(void *i); 
void *watchIncrease(); 
void *watchDecrease(); 

//init globals 
double marketValue; 
int numThreads; 
double *stocks; 
double ceiling; 
double floor_; 
int flag; 

pthread_t *threads; 
pthread_t watchIncreaseThread; 
pthread_t watchDecreaseThread; 
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t threshold_ceiling; 
pthread_cond_t threshold_floor_; 

int main(int argc, char **argv){ 

    numThreads = atoi(argv[1]); 
    int level = atoi(argv[2]); 

    marketValue = 100 * numThreads; 
    //initialize personal stocks for threads 
    stocks = (double *) malloc(sizeof(double) * numThreads); 
    int i; 
    for(i = 0; i < numThreads; i++) stocks[i] = 100; 
    //initialize floor/ceiling 
    double percent = (double) level/100; 

    double cap = marketValue * percent; 
    ceiling = marketValue + cap; 
    floor_ = marketValue - cap; 

    //seed rand() 
    srand(time(NULL)); 
    //create threads 
    pthread_cond_init(&threshold_ceiling,NULL); 
    pthread_cond_init(&threshold_floor_,NULL); 

    int rc = pthread_create(&watchIncreaseThread,NULL,watchIncrease,NULL); 
    assert(rc == 0); 
    rc = pthread_create(&watchDecreaseThread,NULL,watchDecrease,NULL); 
    assert(rc == 0); 

    threads = (pthread_t *)malloc(sizeof(pthread_t) * numThreads); 
    assert(threads != NULL); 
    for(i = 0; i < numThreads; i++){ 
     int rc = pthread_create(&threads[i],NULL,update,(void *)i); 
     assert(rc == 0); 
    } 

    int j; 
    for(j = 0; j < numThreads; j++){ 
     pthread_join(threads[j],NULL); 
    } 

    return 0; 
} 

void *update(void *i){ 

    int index = (int)i; 
    double max = 2; 
    double val; 

    while(1){ 
     int rc = pthread_mutex_lock (&lock); 
     assert(rc == 0); 
     val = max * ((double)rand()/(double)RAND_MAX - 0.5); 
     stocks[index] += val; 

     marketValue += val; 
     pthread_cond_signal (&threshold_ceiling); 
     pthread_cond_signal (&threshold_floor_); 
     pthread_mutex_unlock(&lock); 

    } 

} 

void *watchIncrease(){ 

    int rc = pthread_mutex_lock(&lock); 
    assert(rc == 0); 
    while(marketValue < ceiling){ 
     pthread_cond_wait(&threshold_ceiling, &lock); 
    } 
    printf("Market Up to %.2f\n",marketValue); 
    int i; 
    double sum = 0; 
    for(i = 0; i < numThreads; i++){ 
     sum += stocks[i]; 
    } 
    printf("Total Market Price of %d stocks: %.2f\n",numThreads,sum); 
    for(i = 0; i < numThreads; i++){ 
     rc = pthread_cancel(threads[i]); 
     assert(rc == 0); 
    } 
    pthread_cancel(watchDecreaseThread); 
    pthread_mutex_unlock(&lock); 
    pthread_exit(NULL); 

    //exit(0); 
} 

void *watchDecrease(){ 

    int rc = pthread_mutex_lock(&lock); 
    assert(rc == 0); 
    while(marketValue > floor_){ 
     pthread_cond_wait(&threshold_floor_, &lock); 
    } 
    printf("Market Down to %.2f\n",marketValue); 
    int i; 
    double sum = 0; 
    for(i = 0; i < numThreads; i++){ 
     sum += stocks[i]; 
    } 
    printf("Total Market Price of %d stocks: %.2f\n",numThreads,sum); 
    for(i = 0; i < numThreads; i++){ 
     rc = pthread_cancel(threads[i]); 
     assert(rc == 0); 
    } 
    pthread_cancel(watchIncreaseThread); 
    pthread_mutex_unlock(&lock); 
    pthread_exit(NULL); 
    //exit(0); 


} 
+1

Birincisi, bu kötü bir fikir. İkinci olarak, 'update'de' while'-döngüsü 'pthread_cancel()' tarafından ertelenmiş iptal için iptal noktaları olarak belirtilen hiçbir işlev içermez. Asenkronize kanülasyonu etkinleştirmeye karar verebilirsiniz, ancak sane (r) çözümü, pthread_mutex_unlock() 'dan sonra bir' pthread_testcancel() 'eklemek olacaktır. – EOF

+0

Eklemek için, asenkron iptal etme kesinlikle bu durumda kötü bir fikir değildir, ne pthread_mutex_lock(), pthread_mutex_unlock() veya pthread_cond_signal(), async-cancel safe (https://www.gnu.org) /software/libc/manual/html_node/POSIX-Safety-Concepts.html). Söylendiği gibi, 'while'-döngüsünün başlangıcında ya da sonunda (muteksin kilitlenmediği) bir pthread_testcancel()' ın gitmesi daha iyi bir yol olacaktır. – sonicwave

cevap

İlgili konular