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

Posted

技术标签:

【中文标题】我们可以使用 while 循环和其他线程的全局变量删除等待吗?【英文标题】:can we remove wait using while loop with anything else for global variable of thread? 【发布时间】:2013-08-22 07:00:08 【问题描述】:

在下面的代码中,我尝试使用线程顺序计算 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;

【问题讨论】:

并行还是串行?你想要什么? condX 变量需要防止并发访问。 你可以试试pthread_cond_waitlinux.die.net/man/3/pthread_cond_wait @Rohan:在回答他/她的最后一个问题时,OP 已经向他展示了这一点以及更多内容。 x1 和 x2 应该并行计算,但是在单次计算之后应该调用 x1 和 x2 的下一个计算。 【参考方案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;

【讨论】:

但是,当我打印最终结果时,我实际上需要传递数据(x1 和 x2)以进行其他计算,之后只有我可以移动以进行下一次迭代.. 在这种情况下,我们应该使用 pthread_cond_wait 让主线程为每个循环迭代一个接一个地向每个线程发出信号。这样,主循环可以更新自己的变量,向第一个线程发出信号(使用 pthread_cond_signal),然后向第二个线程发出信号。需要注意的是,我们正在尝试协调 3 个线程,其中一个是主线程。 但是@Manoj 会在发送条件信号后循环等待。我可以等待使用互斥锁..但是循环会等到我锁定线程吗?当我在代码中打印最终结果时。我需要使用 x1 和 x2 添加更多计算......因此需要在那里等待两个线程......这会有帮助吗? 我已经快速编写了您的示例以在主线程和两个线程之间进行协调。我也更新了上面的答案。关键是,现在等待转移到了 pthread_cond_wait(),而不是等待 while 循环。这只是一个示例——请根据您的应用程序需要对其进行修改。 谢谢我会尝试编辑..并会使用你的建议..@Manoj Pandey

以上是关于我们可以使用 while 循环和其他线程的全局变量删除等待吗?的主要内容,如果未能解决你的问题,请参考以下文章

C++控制台程序怎样使主函数无限循环

如何使用定时全局变量影响 bash while 循环?

qt多线程的问题

ThreadLocal和异步

线程之间的通讯问题

在 C 中使用共享变量和互斥锁进行线程同步