2013-02-03 23 views
3

假設此問題: 2方案中,A和B,A的1點的方法,M的M個處理,命名爲VAR 1個共享變量現在1作家,男讀者消耗相同的項目

A 
main(){ 
    int i, a[50]; 
    for(i=0;i<50;i++) 
     var = a[i]; 
} 



B 
main(){ 
    int i, b[50]; 
    for(i=0;i<50;i++) 
     b[i] = var; 
} 

,什麼我需要做的是確保對於A中的每個循環,每個B進程讀取共享變量(一次!)並將其存儲在它們的數組中。所以最後,每個B進程都會在他們的b陣列中有一個a陣列的副本。 這是一個信號量問題,解決方案可能是僞代碼,所以語言無關緊要。

初始解決方案不工作: 我正在使用信號量B初始化爲0,並且每次A寫入某些內容時,我正在通過M增加B,並執行一次下降(A)。 在每個B循環的開始,我做一個向下(B)。然後在B的每個循環結束時,我檢查是否有M讀者已經讀取並存儲了var,如果他們有,我正在做(A)。

顯然上面讓一個單個B過程「消費」都被假定M使用,以通過M讀者傳播。 那麼我該如何 - 智能地 - 確保每個B只讀取一次每個變量?一組M個信號量(每個M都有一個信號量)可以完成這項工作,但這很可能不是該練習所要求的。

+0

爲什麼不使用讀寫鎖? – fge

+0

每個讀者對每個環路做單讀,我需要做的M上的讀者同樣的工作,而不是讓讀者一起工作 – Bimp

回答

1

可以有四個信號燈做到這一點。一個意思是「讀一個平均的位置」。一個意思是「B寫了一個平坦的位置」。一個意思是「讀一個奇怪的位置」。最後的意思是「B寫了一個奇怪的位置」。

A讀取一個[0],然後通知第一旗語M次,然後等待在第二旗語M次。 B寫入b [0],然後發信號通知第二次信號量一次。

然後A讀取一個[1],信號的第三信號的M倍,並且等待在第四信號的M倍。 B寫b [1]併發信號給第四個信號量一次。

然後,你的信號量之間切換爲你處理陣列的奇數/偶數元素。

清晰漂亮的一門功課的問題,因爲這似乎並不像一個真實的場景。

+0

這是不完全的家庭作業(雖然我也認爲它標記爲這樣的,但勸阻因爲它已被棄用),我只是在瀏覽一些舊的考題。這與我的方法非常相似,但我會無論如何接受它。 – Bimp

0

實施

// Before A and any B run, init 2 x M x 50 semaphores 
// (set to 0, but usually they're automatically initialized by the system to 
// something equivalent to 0, meaning no-access) 

// Create [M][50] semaphores and init to no access for Bs 
for (i=0 ; i<M ; i++) 
    for (j=0 ; j<50 ; j++) 
    asems[i][j] = 0; // no access for Bi index j 


// Create [M][50] semaphores to block A before it goes to next iteration 
for (i=0 ; i<M ; i++) 
    for (j=0 ; j<50 ; j++) 
    bsems[i][j] = 0; // no access for A until all B's say ok for that index 


// A 

for (i=0 ; i<50 ; i++) { 
    var = a[i]; 

    // release a-sems and, then, wait for b-sems in two separate loops 
    // or you may have a deadlock if you use one loop only... 
    // (since we don't know if B[i] always ends before B[i+1]) 
    for (j=0 ; j<M ; j++) { 
     release (asems[j][i]) 
    } 
    for (j=0 ; j<M ; j++) { 
     wait (bsems[j][i]) 
    } 
} 

// a B 

ME = id // id is the B's unique id from 0 to 49 

for (i=0 ; i<50 ; i++) { 
    wait (asems[ME][i]) 
    b[i] = var 
    relase (bsems[ME][i]) 
} 

更復雜的算法的一個爲例可以由僅使用[50](而不是[M] [50)的信號量。通常等待釋放通過類似的東西(系統處理)介紹,他們每跑在關鍵部分

wait (sem) { 
    wait_in_sem_fifo_until (sem > 0) 
    sem-- 
} 

release (sem) { 
    sem++ 
}