使用pthreads - C 杀死线程

3

我有一个C pthread 程序,在主线程中创建了N个更新全局变量的线程。主线程还调用pthread_join等待这些更新线程完成。我还有2个监视线程,它们使用pthread条件变量来检查全局变量是否超过或低于某些数字,如果是,就会终止所有更新线程和另一个监视线程。然而,我在最后一部分遇到了麻烦...杀死其他线程。我的程序做了它应该做的事情,但从未完成...它只是卡住了。在每个观察线程结束时调用exit(0)可以解决问题,但我觉得这太懒了,我真的想学习如何从单独的线程中杀死其他线程并返回到主函数。

以下是我的代码:

#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
首先,这是一个不好的想法。其次,在update()中的while循环中没有指定作为pthread_cancel()取消点的函数。您可以决定启用异步取消,但更明智的解决方案是在pthread_mutex_unlock()之后添加pthread_testcancel() - EOF
仅仅补充一下,异步取消在这种情况下绝对不是个好主意,因为 pthread_mutex_lock()pthread_mutex_unlock()pthread_cond_signal() 都不是异步取消安全 ( https://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html )。如前所述,在 while 循环的开头或结尾(互斥锁未被锁定的位置)执行 pthread_testcancel() 是更好的选择。 - sonicwave
1个回答

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接