如何使用互斥体和条件优雅地退出线程

问题描述 投票:0回答:1

下面的演示使用互斥锁来保护共享变量

sum
,线程一等待线程二的信号来操作变量
sum
,线程三监视变量
sum
以销毁互斥锁。现在工作正常了。

我想知道是否有什么可以让代码变得更好?

#include <pthread.h>
#include <mutex>
#include <time.h>
#include <unistd.h>
// g++ -std=c++11 -Werror -pthread mutex_demo.cpp -o out.binaa

#define N 100
long long sum = 0;
    
pthread_mutex_t m_lock;// = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t m_cond;
 int timeout = 1000000;
bool destoried = false;

void print( const char *fmt,...) {
    va_list vlist;
    printf("%d %d ", getpid(), gettid());
    va_start(vlist, fmt);
    vprintf(fmt, vlist);
    va_end(vlist);
    fflush(stdout);
    return;
}

void* threadLoop1(void * arg) {
    int offset = *(int*)arg;
    for (uint32_t i=0;i<N;i++) {
       if (destoried == true) break;
        pthread_mutex_lock(&m_lock);
        pthread_cond_wait(&m_cond, &m_lock);
        sum += offset;
        print("1 => %lld\n",sum);
        usleep(timeout/2);
        pthread_mutex_unlock(&m_lock);
    }
    print("1 exit1\n");
    return NULL;
}

int step = 5;

void* threadLoop2(void * arg) {
    int offset = *(int*)arg;
    for (uint32_t i=0;i<N;i++) {
       if (destoried == true) break;
        pthread_mutex_lock(&m_lock);
        sum += offset;
        print("2 => %lld %d\n",sum,step);
        if (sum + offset >= step) {
            pthread_cond_signal(&m_cond);
            step += 5;
        }
        usleep(timeout/2);
        pthread_mutex_unlock(&m_lock);
    }
    print("2 exit1\n");
    return NULL;
}

void* threadLoop3(void * arg) {
    while (1) {
        if (sum > 10) {
           destoried = true;
            pthread_cond_signal(&m_cond);
            pthread_cond_destroy(&m_cond);
            pthread_mutex_destroy(&m_lock);
            break;
        }
        usleep(timeout/2);
    }
    print("3 exit1\n");
    return NULL;
}

int mutex_test() {
    pthread_cond_init(&m_cond, NULL);
    pthread_mutex_init(&m_lock,NULL);

    int offset1 = 1;
    pthread_t tid1;
    pthread_create(&tid1,NULL,threadLoop1,&offset1);

    int offset2 = 1;
    pthread_t tid2;
    pthread_create(&tid2,NULL,threadLoop2,&offset2);

    pthread_t tid3;
    pthread_create(&tid3,NULL,threadLoop3,NULL);
    
    pthread_cond_signal(&m_cond);

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    print("done\n");
    return 0;
}

我的问题:

  1. 布尔变量
    destoried
    看起来不是一个好方法。
  2. 在变量地址上调用destory互斥体,如果不调用destory,是否会导致资源泄漏?
c pthreads mutex
1个回答
0
投票

您可以为

destoried
变量使用更具描述性的名称,例如
shouldDestroy
,以明确它是一个指示是否应销毁互斥锁的标志。

然后,最好将它们作为参数传递给创建它们的函数,而不是直接在互斥体和条件变量地址上调用 pthread_mutex_destroy 和 pthread_cond_destroy 。这样,即使在创建过程中出现错误,也可以确保资源得到正确的清理。例如:

bool shouldDestroy = false;

void destroyMutexAndCondition(pthread_mutex_t* mutex, pthread_cond_t* condition) {
    pthread_cond_destroy(condition);
    pthread_mutex_destroy(mutex);
}

void* threadLoop3(void* arg) {
    while (1) {
        if (sum > 10) {
            shouldDestroy = true;
            pthread_cond_signal(&m_cond);
            destroyMutexAndCondition(&m_lock, &m_cond);
            break;
        }
        usleep(timeout/2);
    }
    print("3 exit1\n");
    return NULL;
}

int mutex_test() {
    pthread_cond_init(&m_cond, NULL);
    pthread_mutex_init(&m_lock,NULL);

    // ...

    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);

    if (!shouldDestroy) {
        destroyMutexAndCondition(&m_lock, &m_cond);
    }

    print("done\n");
    return 0;
}

在我的代码中,添加了一个新函数

destroyMutexAndCondition
来处理互斥锁和条件变量的销毁。 当
destroyMutexAndCondition
设置为
threadLoop3
时,会在
shouldDestroy
中调用
true
函数。 如果在
shouldDestroy
结束时
true
未设置为
mutex_test
,则调用
destroyMutexAndCondition
函数以确保资源被清理。

© www.soinside.com 2019 - 2024. All rights reserved.