【问题标题】:c - running 2 threads in parallel with a shared variablec - 使用共享变量并行运行 2 个线程
【发布时间】:2016-06-26 12:55:41
【问题描述】:

只是线程的初学者,我只是在做一个涉及这两个线程的任务。

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

int count = 0;

void waitFor(unsigned int secs)
{
    unsigned int retTime = time(0) + secs;
    while(time(0) < retTime);
}

void func1(void * args)
{
    printf("In func1 ...\n");
    long i = 0;
    while(1){
        i++;
        if(count == 1)
            break;
    }
    printf("The total number counted is: %ld \n", i);
    count = 0;
    i = 0;
}

void func2(void * args)
{
    printf("In func2 ...\n");
    waitFor(3);
    count = 1;
}


int main()
{
    pthread_t th1, th2;

    int j = 0;
    while(j++ < 4){
        printf("\nRound:\t%d\n", j);

        pthread_create(&th1, NULL, (void*)func1,NULL);
        pthread_create(&th2, NULL, (void*)func2, NULL);

        pthread_join(th1,NULL);
        pthread_join(th2,NULL);
        waitFor(3);
    }

    return 0;
}

我已经阅读了各种参考资料,据我了解,pthread_join() 意味着如果有 2 个或更多线程,那么它们将等待一个线程完成其执行,然后下一个线程将开始执行,依此类推。

但是当我运行这个程序时,在执行 pthread_join(th1) 的那一刻,两个线程都被创建并“同时”执行。这是怎么回事? 输出:

Round:  1
In func2 ...
In func1 ...
The total number counted is: 897651254 

Round:  2
In func1 ...
In func2 ...
The total number counted is: 1051386065

........

我的目标是并行运行这 2 个线程。现在, join 似乎可以做到这一点;还是我哪里出错了?

而且我已经读到 C 中的线程不首选使用 volatile。那么有什么方法可以使用 count 作为线程 2 到 1 的信号吗?

【问题讨论】:

  • 您在哪里读到“如果有 2 个或更多线程,那么它们将等待一个线程完成其执行,然后下一个线程将开始执行”? Pthread_join 只是等待您作为参数提供的线程终止。是什么让您认为您的踏板是在您调用 pthread_join 时创建的?您的线程是使用 pthread_create 创建和启动的。
  • 需要保护对共享变量(此处为count)的并发读/写访问。这通常使用互斥锁来完成。请参阅上面的 pthread_mutex_*() 函数。
  • @alk,如果我在 func2 中锁定计数,在 func2 解锁计数之前,我的整个 func1 不会停止吗?或者直到func1中的'count'语句被执行并等待func2解锁它?那么这意味着没有并发对吗?
  • 如果任何答案解决了您的问题,请单击大复选框接受它作为答案。这将向社区表明您找到了解决方案,并将给您和回答者一些声誉。

标签: c multithreading pthreads volatile


【解决方案1】:

引用:

我的理解pthread_join()的意思是如果有2个或更多线程,那么它们会等待一个线程完成它的执行,然后下一个开始执行,依此类推

这是不正确的。加入只是意味着进程一直等待,直到线程终止。

引用:

在执行 pthread_join(th1) 的那一刻,两个线程都被创建并“同时”执行。

这是不正确的。线程在调用pthread_create 时创建并启动 注意:start 我的意思是它们已准备好执行。但是,由操作系统决定它们何时实际执行,因此它们可能需要一些时间才能执行。

要在两个线程之间共享count,您可以使用互斥锁。

int count = 0;
pthread_mutex_t lock;

访问count时,必须先锁定互斥体,读/写变量,解锁互斥体。

例子:

pthread_mutex_lock(&lock);
count = 1;
pthread_mutex_unlock(&lock);

例子:

long i = 0;
while(1)
{
    ... code not using count ....

    pthread_mutex_lock(&lock);
    if(count == 1) 
    {
        pthread_mutex_unlock(&lock);
        break;
    }
    pthread_mutex_unlock(&lock);

    ... code not using count ....
}

main 中,您需要像这样初始化互斥锁:

pthread_mutex_init(&lock,NULL);

【讨论】:

  • 我知道线程在我们执行“pthread_create”的那一刻开始执行。这是否意味着并行执行?当我尝试不使用“pthread_join”时,我的线程 2 甚至都没有启动。为什么?
  • @infoseeker - 是的,并行。但是并行的含义可能因系统而异。简单的单核 CPU 只使用分时,而多核 CPU 可以真正并行运行线程。
  • @infoseeker Quote: without 'pthread_join', my thread 2 doesn't even start. Why? 如果没有有关您系统的详细信息,我无法知道。猜测可能是 mainthreads 实际执行之前完成。在任何情况下,连接都是必需的,因为您需要等待线程终止
  • @infoseeker:请致电pthread_exit() 离开main()。它只不过是另一个线程而已。如果main() 以简单的returning 结束,那么整个进程将连同它的所有线程一起结束。后者看起来好像线程甚至没有启动。
  • 您可能想提一下,仅定义一个互斥变量(如您的代码 sn-p 所示)不足以使用它。它需要预先初始化。
猜你喜欢
  • 1970-01-01
  • 2016-02-09
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
  • 1970-01-01
相关资源
最近更新 更多