2012-05-23 64 views
4

我读了一本书,给出了下面的例子:并行线程/等待(状态)

int value=0 
int thread_func(int id) { 
    int temp; 
    temp=value+id; 
    printf("Thread%d value: %d", id, temp); 
    value=temp; 
} 

int main() { 
    int fork_id, status, i; 
    pthread_t tids[3]; 
    fork_id=fork(); 
if (fork_id == 0) { 
    for (i=1; i≤3; i++) 
     pthread_create(&tids[i-1], NULL, thread_func, i); 
     for (i=0; i≤2; i++) 
     pthread_join(tids+i, &status); 
     printf("Second process value: %d", value); 
    } 
else { 
    wait(&status); 
     printf("First process value: %d", value) 
     } 

我不明白两两件事: 当我读到,该行已在printf("First process value: %d", value)是唯一的价值0. 但是为什么?等待(&状态)将一直等到子进程终止。在这种情况下,只有在所有连接都完成后才会终止。意思是,当值为6.

其次,在行printf("Second process value: %d", value);,值可以从1到6.这也很奇怪,因为我们有连接指令。

回答

3

的问题的答案:

  1. 的值将是在父进程0,因为当fork发生父的地址空间被复制(连同可变value)在子​​进程。因此,虽然value在孩子中发生了变化,但这一变化并不反映在父母中,因为它们是不同的变量。

  2. 由于没有涉及同步,因此无法知道变量value被三个子线程更改的顺序。具体来说,每个线程都有一个带有不同值的本地temp变量,然后将其复制到全局变量value中,但无法知道线程将以何种顺序覆盖value,其中temp这里是:value = temp;。因此,其执行价值可能会有所不同。

+0

谢谢你的回答。关于我的第二个问题:我们真的不知道三个子线程的变量值是以哪种顺序变化的,但是我们可以知道,在所有三个线程完成后(因为连接指令),我们将到达这一行。我错过了什么? –

+1

@Adam Sh:问题是,例如在一次执行中,第一个线程使'temp = 0 + 1',然后设置'value = 1'。然后第二个线程到达,使'temp = 1 + 2'然后设置'value = 3',最后一个线程使'temp = 3 + 3'并设置'value = 6'。在另一个可能的执行过程中,第一个线程设置'temp = 0 + 1',但是在达到'temp = value'之前,第二个线程'temp = 0 + 2'(因为线程1没有达到'temp = value')然后使'值= 2'。现在你可以看到最终的价值会完全不同。 – Tudor

0

因为当你fork的时候,你会得到一个拥有自己内存的全新进程,这意味着在一个进程中变量的更改不会显示在另一个进程中。另一方面,线程共享内存,这意味着线程化程序中变量的变化显示在所有线程中。

0

值由子进程递增,所以为0。

if(fork_id == 0){ 
...... 
...... 
} 

是由产生的线程子执行父进程将显示其价值。

和子进程有不同的内存副本。所以增加孩子的价值对父母来说并不意味着同样的价值。

线程可以访问全局值。