简体   繁体   English

使用pthreads杀死线程 - C.

[英]Killing Threads with pthreads - C

I have a C pthread program that creates N threads in main that update a global variable. 我有一个C pthread程序,在main中创建N个线程来更新全局变量。 Main also calls pthread_join on all of these update threads to wait for them to finish. Main还在所有这些更新线程上调用pthread_join以等待它们完成。 I also have 2 watcher threads that use pthread condition variables to check to see if the global variable goes above or below certain numbers, and if so, it kills all update threads and the other watcher thread. 我还有2个观察者线程使用pthread条件变量来检查全局变量是高于还是低于某些数字,如果是,它会杀死所有更新线程和其他观察者线程。 However, I'm having trouble with this last part..killing the other threads. 但是,我在这最后一部分遇到了麻烦..杀死其他线程。 My program does what it is supposed to do but never completes... it just gets stuck. 我的程序完成它应该做的但却永远不会完成...它只是卡住了。 Calling exit(0) at the end of each watcher thread works but I feel like that's too lazy of a solution, I'd really like to learn how to kill other threads from a separate thread and return to main. 在每个观察者线程结束时调用exit(0)可以正常工作,但我觉得这个解决方案太懒了,我真的想学习如何从一个单独的线程中杀死其他线程并返回main。

Here's my code: 这是我的代码:

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


}

pthread_cancel is discouraged, instead the proper way of doing this is replacing while(1){ by while(!killed[index]){ . 不鼓励pthread_cancel ,而是正确的方法是替换while(1){ by while(!killed[index]){ Then, to kill a thread you set killed[index] . 然后,杀死你设置的线程killed[index] If you have C11 compiler, use http://en.cppreference.com/w/c/atomic/atomic_flag , otherwise you may need a pthread_mutex to protect the killed array. 如果你有C11编译器,请使用http://en.cppreference.com/w/c/atomic/atomic_flag ,否则你可能需要一个pthread_mutex来保护被killed数组。

Example: https://gustedt.wordpress.com/2012/01/22/simple-c11-atomics-atomic_flag/ 示例: https//gustedt.wordpress.com/2012/01/22/simple-c11-atomics-atomic_flag/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM