2011-10-31 91 views
4

编辑: 我做了一个错误的假设,当它们实际上开始在pthread_create上运行时,线程开始在pthread_join上运行。pthread_join()是否允许执行调用线程继续?


我学习使用POSIX线程,和我读过:
pthread_join() - wait for thread termination

所以,代码样本中,主要的退出(0)没有达到,直到两个启动的线程结束。
但是在第一次调用pthread_join()之后,main继续执行,因为第二次调用pthread_join()实际上运行,并且中间的消息被打印。
那么这是怎么回事?当两个线程还没有完成时,main是否继续执行?或不是吗?
我知道这不是一种可靠的测试方法,但是无论循环多长时间,在两个线程完成后总是会打印第二条测试消息。 (至少在我的机器上时,我试了一下)

 
void *print_message_function(void *ptr) 
{ 
    char *message = (char *) ptr; 
    for(int a = 0; a < 1000; ++a) 
     printf("%s - %i\n", message, a); 
    return NULL; 
} 
// 
int main(int argc, char *argv[]) 
{ 
    pthread_t thread1, thread2; 
    char message1[] = "Thread 1"; 
    char message2[] = "Thread 2"; 
    int iret1, iret2; 
    // 
    iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1); 
    iret2 = pthread_create(&thread2, NULL, print_message_function, (void*) message2); 
    // 
    pthread_join(thread1, NULL); 
    printf("Let's see when is this printed...\n"); 
    pthread_join(thread2, NULL); 
    printf("And this one?...\n"); 
    // 
    printf("Thread 1 returns: %d\n",iret1); 
    printf("Thread 2 returns: %d\n",iret2); 
    exit(0); 
} 

回答

6

功能pthread_join等待线程完成,或者线程已经完成立即返回。

你的情况

所以

pthread_join(thread1, NULL); /* Start waiting for thread1. */ 
printf("Let's see when is this printed...\n"); /* Done waiting for thread1. */ 

pthread_join(thread2, NULL); /* Start waiting for thread2. */ 
printf("And this one?...\n"); /* Done waiting for thread2. */ 

但经过第一次调用在pthread_join(),主继续执行, 因为第二次调用在pthread_join()实际运行,而它们之间的 消息打印。

假。除非线程1已经完成,否则等待pthread_join

+0

哦对,因为线程已经在pthread_create上启动了。 thx – Petruza

3
pthread_join(thread1, NULL); 

主线程在这里等待在此加入通话,直到thread1完成了工作。一旦thread1完成执行主线程将继续并执行下一条语句printf

printf("Let's see when is this printed...\n"); 

再次,主线程将在这里等待,直到thread2完成其工作。

pthread_join(thread2, NULL); 

一旦thread2完成了工作主线向前推进,并执行下一条语句这是printf

printf("And this one?...\n"); 

该序列将以上述方式工作。可能发生这种情况的时间太早,导致您看到的痕迹变得混乱。
另外,不要使用printf看多线程程序的行为可以说是相当具误导性,中的printf的顺序可能并不总是指示正确的控制流,因为它基于计时和缓冲区到标准输出的冲洗可能不会在SASME顺序发生因为这些打印是通过线程执行的。

+0

谢谢,请参阅编辑。 – Petruza

3
pthread_join()

不返回(阻塞调用线程),直到被连接的线程已终止。如果线程已经终止,那么它马上返回。

在你的测试中,两个线程都退出,所以当然你会看到从主线程打印的所有消息。当第一条消息被打印时,您知道thread1已完成;当第二个打印时,你知道thread2也是完整的。这可能会在第一次之后很快发生,因为这两个线程大致同时进行了相同的工作量。

2

如果第一个pthread_join立即返回,则表明第一个线程已经完成执行。输出是什么样的?在“让我们看看它何时被打印”之后,您是否看到任何“Thread 1 - n”输出?