我们可以使用 while 循环和线程的全局变量的其他任何东西来删除等待吗?

标签 c multithreading mutex semaphore

Explanation of problem

在下面的代码中,我尝试使用线程顺序计算 x1 和 x2 的值。(在实际情况下,x1 和 x2 将是大计算量) 但是等待两个线程使用 while 循环计算各自变量的值对处理器来说成本越来越高。 问题是,我希望两个线程并行运行,但是两个线程的循环应该同样序列化(意味着应该在一次调用中运行一次)。 因此,有什么方法可以删除这些 while 循环并连续获取结果。我对使用信号量和互斥锁感到很困惑,因为 x1 和 x2 是独立的 彼此的?请帮忙。提前致谢。

#include <stdio.h>
#include <pthread.h>

pthread_t pth1,pth2;
//Values to calculate
int x1 = 0, x2 = 0;
//Values for condition
int cond1 = 0,cond2 = 0;


void *threadfunc1(void *parm)
{
    for (;;) {
        // Is this while loop is very costly for the processor?
        while(!cond1) {}
        x1++;
        cond1 = 0;
    }
    return NULL ;
}
void *threadfunc2(void *parm)
{
    for (;;) {
        // Is this while loop is very costly for the processor?
        while(!cond2) {}
        x2++;
        cond2 = 0;
    }
    return NULL ;
}



int main () {
    pthread_create(&pth1, NULL, threadfunc1, "foo");
    pthread_create(&pth2, NULL, threadfunc2, "foo");
    int loop = 0;
    while (loop < 10) {
        // iterated as a step
        loop++;
        printf("Initial : x1 = %d, x2 = %d\n", x1, x2);
        cond1 = 1;
        cond2 = 1;
        // Is this while loop is very costly for the processor?
        while(cond1) {}
        while(cond2) {}
        printf("Final   : x1 = %d, x2 = %d\n", x1, x2);
    }

    pthread_cancel(pth1);
    pthread_cancel(pth2);
    return 1;
}

最佳答案

如果您删除 threadfunc1 和 threadfunc2 中的 while 循环,那么线程将返回而不继续。因此,您肯定需要一种方法让线程保持事件状态,直到它完成对系列的计算(在本例中为 10)。

这是一个示例代码,显示了尝试在主线程和两个线程之间进行协调。使用 pthread_cond_wait(),等待从简单的“while”循环转移到 pthread_cond_wait()。

#include <stdio.h>
#include <pthread.h>

//Values to calculate
int x1 = 0, x2 = 0;
//Values for condition
int cond1 = 0, cond2 = 0;

static pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;

void *threadfunc1(void *parm) {
    int i = 0;
    while (i < 10) {
        printf("\t\tThread1 with x1 = %d\n", x1);
        pthread_mutex_lock(&m1);
        if (cond1 == 0) {
            pthread_cond_wait(&c, &m1);
        }
        x1++;
        cond1 = 0;
        pthread_mutex_unlock(&m1);
        i++;
    }
    printf("\t\tThread1 returns with x1 = %d\n", x1);
    return NULL ;
}

void *threadfunc2(void *parm) {
    int i = 0;
    while (i < 10) {
        printf("\t\tThread2 with x2 = %d\n", x2);
        pthread_mutex_lock(&m2);
        if (cond2 == 0) {
            pthread_cond_wait(&c, &m2);
        }
        x2++;
        cond2 = 0;
        pthread_mutex_unlock(&m2);
        i++;
    }
    printf("\t\tThread2 returns with x2 = %d\n", x2);
    return NULL ;
}


int main () {
    pthread_t pth1, pth2;
    pthread_create(&pth1, NULL, threadfunc1, "foo");
    pthread_create(&pth2, NULL, threadfunc2, "foo");
    int retVal;
    int loop = 0;
    while (loop <= 10) {
        loop++;
        cond1 = 1;
        pthread_cond_signal(&c);

        cond2 = 1;
        pthread_cond_signal(&c);
        printf("Loop [%d]: x1 = %d, x2 = %d\n", loop, x1, x2);
    }

    retVal = pthread_join(pth1, NULL);
    retVal = pthread_join(pth2, NULL);
    printf("Final : x1 = %d, x2 = %d\n", x1, x2);
    return 0;
}

关于我们可以使用 while 循环和线程的全局变量的其他任何东西来删除等待吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18373692/

相关文章:

java - 多线程 JNI 调用

c - Mutex - 使用线程计算文件中 char 的出现次数

c - 如何使用指向 C 数据的指针写入 Golang 中的文件?

c - C 中 ","运算符的不明确行为

c - 相当于c中的strcpy函数,int main以及一些解释

c++ - 为什么我们保留互斥量而不是每次都在守卫之前声明它?

arrays - 尝试仅将唯一元素添加到数组中

c++ - 椭圆滤波器代码

java - 在多线程环境中访问大型单例对象

multithreading - 使用 Stanford CoreNLP (3.5.2) 进行并发处理