2012-08-07 25 views
2

我試圖使此代碼正常工作時遇到問題。我想要做的是讓我的程序並行計算一些特定的算法。有些時候它有效,有些時候卻不行。這種情況經常發生在我用大數字運行時,但我可以在頂部(linux命令)看到很多已停止的進程,我認爲這是因爲我的分支正在結束異步並且有些孩子被拋在後面。但是我一開始認爲我的邏輯至少可以完成所有的計算,因爲我已經設置了2個控制變量,標誌和alldone,它們都是共享內存空間,並且用於完成while循環。我一直在尋找一些光,現在我來這裏尋求幫助,因爲我找不到能幫助我的東西。任何人都可以用我的邏輯問題在下面的代碼中幫助我,以某種方式我的流程可以按照正確的順序完成,避免將流程停滯在後面?提前致謝!C編程邏輯 - 試圖完成線程(fork)並且不會離開不可用的進程

for(i=0;i<numforks*sizeof(int);i++) 
     flags[i] = 0; 

    *alldone = numforks; 
    pid = fork(); 

    if(pid==0) { 
     pid1 = fork(); 
     pid2 = fork(); 
     pid3 = fork(); 

     #ifdef DEBUG_F 
      printf("worker process\n"); 
     #endif 

     do { 
      thisfork = thisfork -1; 
      if(flags[thisfork] == 0){ 
       flags[thisfork] = 1; 
       #ifdef DEBUG_THREADS 
        printf("flags[%d] was zero now is %d\n", thisfork, flags[thisfork]); 
       #endif 
       if(thisfork == 7) { 
        heme(0,riall,chunk_size,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 6) { 
        heme(chunk_size,riall,chunk_size*2,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 5) { 
        heme(chunk_size*2,riall,chunk_size*3,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 4) { 
        heme(chunk_size*3,riall,chunk_size*4,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 3) { 
        heme(chunk_size*4,riall,chunk_size*5,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 2) { 
        heme(chunk_size*5,riall,chunk_size*6,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 1) { 
        heme(chunk_size*6,riall,chunk_size*7,r,pp,qq); 
        (*alldone)--; 
       } 
       if(thisfork == 0) { 
        heme(chunk_size*7,riall,chunk_size*8,r,pp,qq); 
        (*alldone)--; 
       } 
      } 
     } while(thisfork > 0 && alldone > 0); 

     exit(0); 

    } else { 
     wait(&stat); 
    } 
+0

一個不存在的進程只佔用足夠的內存來存儲執行時間等統計信息。它也佔用了進程表中的一個插槽,但除非您分出一個大數字,否則不會造成任何問題。 – Spaceghost 2012-08-07 22:16:50

回答

1

如果alldone在共享內存中,那麼您需要應用原子減量。否則,您的alldone計數器可能會處於不一致的狀態。如果您正在使用GCC,則可以使用內置函數來執行遞減操作。

__sync_sub_and_fetch(alldone, 1); 
+0

有趣,所以我認爲這也適用於標誌操縱,對吧? – 2012-08-07 22:31:07

+0

@ user1583145:如果多個進程操作相同的標誌,那麼您將需要使用原子。查看[關於原子構建的gcc文檔](http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html)。 – jxh 2012-08-07 22:35:27

1

您在上面的代碼中啓動了多個子項,但您只需撥打wait()一次。你需要等待所有的孩子終止,而不僅僅是其中的一個。

+0

是的,我知道。我試圖實現這一目標,但仍試圖使我的邏輯工作......第一個等待是在所有孩子完成計算heme函數中的塊後繼續進行計算的主進程。我認爲如果計算正確,離開不存在的流程就不會成爲問題。我正在看看__sync_sub_and_fetch – 2012-08-07 22:37:22

1

這是不相關的問題,但你真的應該改變這樣的:

if(thisfork == 7) { 
    heme(0,riall,chunk_size,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 6) { 
    heme(chunk_size,riall,chunk_size*2,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 5) { 
    heme(chunk_size*2,riall,chunk_size*3,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 4) { 
    heme(chunk_size*3,riall,chunk_size*4,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 3) { 
    heme(chunk_size*4,riall,chunk_size*5,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 2) { 
    heme(chunk_size*5,riall,chunk_size*6,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 1) { 
    heme(chunk_size*6,riall,chunk_size*7,r,pp,qq); 
    (*alldone)--; 
} 
if(thisfork == 0) { 
    heme(chunk_size*7,riall,chunk_size*8,r,pp,qq); 
    (*alldone)--; 
} 

這樣:

if(thisfork >= 0 && thisfork <=7){ 
    heme((7 - thisfork),riall,chunk_size*(8 - thisfork),r,pp,qq); 
    (*alldone)--; 
} 
+0

的使用情況謝謝你的建議,我同意你說的看起來好多了,小巧,再次謝謝 編輯:heme(chunk_size *(7 - thisfork),riall,chunk_size * (8 - thisfork),r,pp,qq); – 2012-08-07 22:38:41

+0

沒問題,很樂意幫忙 – 2012-08-07 22:43:37

0

可以使用wait()功能,停止你的父進程,直到你的孩子終止或完成。