2012-05-18 53 views
1

我读了一本书,这给下一个代码:的Posix /线程加入

void *printme(void *id) { 
    int *i; 
    i = (int *)id; 
    printf("Hi. I'm thread %d\n", *i); 
    return NULL; 
} 

void main() { 
    int i, vals[4]; 
    pthread_t tids[4]; 
    void *retval; 
    for (i = 0; i < 4; i++) { 
     vals[i] = i; 
     pthread_create(tids+i, NULL, printme, vals+i); 
    } 
    for (i = 0; i < 4; i++) { 
     printf("Trying to join with tid%d\n", i); 
     pthread_join(tids[i], &retval); 
     printf("Joined with tid%d\n", i); 
    } 
} 

和未来可能的输出:

Trying to join with tid0 
Hi. I'm thread 0 
Hi. I'm thread 1 
Hi. I'm thread 2 
Hi. I'm thread 3 
Joined with tid0 
Trying to join with tid1 
Joined with tid1 
Trying to join with tid2 
Joined with tid2 
Trying to join with tid3 
Joined with tid3 

而且我不明白这怎么可能。我们从主线程开始,创建4个线程:tids[0]... tids[3]。然后,我们暂停执行(通过加入指令):主线程将等待tids[0]停止执行,tids[0]将等待到tids[1]等等。

所以输出应该是:

Hi. I'm thread 0 
Hi. I'm thread 1 
Hi. I'm thread 2 
Hi. I'm thread 3 
Trying to join with tid0 
Trying to join with tid1 
Joined with tid0 
Trying to join with tid2 
Joined with tid1 
Trying to join with tid3 
Joined with tid2 
Joined with tid3 

我觉得我不明白真正的基本的东西。谢谢。

回答

2

我想你错过的是pthread_createfork完全不同。创建的线程从提供的函数开始(在这种情况下为printme),并在该函数返回时立即退出。因此,新创建的线程都不会到达第二个for循环。

+0

线程有另一个执行空间,他们只是执行该函数,他们不会期望到达第二个循环,他们的执行将只是printme。他们无法处理任何订单,所以在这种情况下,所有线程都会被创建,并且控制权仍在主线程中。当连接被调用时,它会进入睡眠状态,任何线程都可以工作。它返回并释放本身的连接。 – Mustafa

2

当您创建新线程pthread_create时,线程#1和主线程并行工作。主要进入phtread_join的下一条指令并挂起,直到线程#1结束。这就是为什么你试图加入tid0,然后你好我是线程#1。

请注意,主线程将按照指定的顺序连接子线程。这意味着当线程#1,线程#2和线程#3和线程1需要10秒执行时,线程2需要6秒执行,线程3需要7秒执行,那么第一次连接将在10秒,然后在几毫秒内你应该有下一个连接,因为所有其他线程应该完成他们的工作。