pthread_join()用于异步线程

时间:2014-11-12 19:45:29

标签: c multithreading asynchronous pthreads pthread-join

我编写了一个简单的演示程序,以便我能理解 pthread_join()函数。

我知道如何使用 pthread_condition_wait()函数来允许异步线程,但我正在尝试理解如何使用 pthread_join()函数执行类似的工作

在下面的程序中,我将线程1s ID传递给线程2s 功能。在线程2s 函数内部,我调用 pthread_join()函数并传入线程1s ID。我希望这会导致线程1 首先运行,然后线程2 运行第二,但我得到的是它们都同时运行。

这是因为一次只有一个线程可以使用 pthread_join()函数,当我从中调用它时,我已经在使用 pthread_join()函数主线程

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

void *functionCount1();
void *functionCount2(void*);

int main()
{

    /* 
        How to Compile
         gcc -c foo
         gcc -pthread -o foo foo.o
    */

    printf("\n\n");

    int rc;
    pthread_t thread1, thread2;

    /* Create two thread --I took out error checking for clarity*/
    pthread_create( &thread1, NULL, &functionCount1, NULL)
    pthread_create( &thread2, NULL, &functionCount2, &thread1)

    pthread_join( thread1, NULL);
    pthread_join( thread2, NULL);

    printf("\n\n");
    exit(0);
}

void *functionCount1()
{

    printf("\nFunction 1");
        sleep(5);
    printf("\nFunction 1");

    return(NULL);
}

void *functionCount2(void* argument)
{

    pthread_t* threadID = (pthread_t*) argument;

    pthread_join(*threadID, NULL);

    printf("\nFunction 2");
        sleep(5);
    printf("\nFunction 2");

    return(NULL);
}

输出:

enter image description here

3 个答案:

答案 0 :(得分:6)

当使用pthread_create()创建线程时,两个线程同时开始执行,并且它们的执行顺序没有固定的顺序。该顺序取决于操作系统的调度和可用的处理器数量等。无论如何,无论如何都无法确定,无论如何都是线程的点。

调用pthread_join()时会发生什么,调用者等待加入的线程终止。因此主线程等待thread1终止,然后等待thread2。但是当主等待thread1时,thread2可能已经完成执行并已经终止。在这种情况下,pthread_join(thread2, NULL);会立即返回。

您的代码中存在更大的问题。您正在将thread1的ID传递给thread2。但是如果thread1thread2开始之前完成执行,那么您将使用无效的线程标识符,导致未定义的行为。另一个问题是您的主要帖子和thread2都试图加入thread1。简而言之,pthread_join()不是多线程之间同步的正确工具。如您所述,您正在使用条件变量/互斥量来实现此目的。

我建议你从pthread_join()删除thread2,修复未定义的行为,如果你想要线程的串行执行,那么你必须一个接一个地创建线程并让它们等待前一个线程终止(pthread_join())。但这样做的实际用处很少。或者让线程在做任何事情之前等待一个条件变量,你可以让线程按照你想要的顺序使用条件变量进行通信。

答案 1 :(得分:3)

您调用未定义的行为。手册页: http://man7.org/linux/man-pages/man3/pthread_join.3.html

Joining with a thread that has previously been joined results in undefined behavior.

第一个线程也可能在第二个线程之前完成exectution。如果你想要这样的东西,那么使用pthread_cond_wait()会更好。

答案 2 :(得分:1)

来自pthread_join man page(强调我的):

  

如果多个线程同时尝试使用同一个线程加入,则结果是未定义的。如果取消调用pthread_join()的线程,则目标线程将保持可连接状态(即,它不会分开)。

看起来你正是在这种情况下,主线程和线程2都试图pthread_join线程1。

您应该为每个线程明确定义一个负责管理的“所有者线程”。责任链应该形成一个分层的线程树(即没有循环或多个父母)。