2012-03-06 83 views
0

我在客戶端(使用GUI和套接字)上工作。 GUI(在主線程上運行)隨時創建我的協議的命令,每當我創建一個新命令時,我都會將它添加到動態堆棧中。線程之間同步堆棧

在另一個線程(使用pthread)中,我檢查堆棧中是否有命令,然後使用套接字(它是非塊btw)逐步發送它。當堆棧頂部的命令完成發送時,彈出堆棧(這意味着該命令被刪除,並且第一個元素下面的每個命令都被推送)。

現在,你可能會猜到我有很大的問題來同步...我嘗試使用一些標誌,互斥鎖,但我總是以內存訪問衝突結束。

基本上什麼Im做是這樣的:

在主線程時(即)用戶按下一個按鈕:

char cmd[ 50 ] = "My new protocol command"; 

AppendCommandToSendStack(cmd); 

在另一個線程:

if(SendStackCount) 
{ 
    SendCommand(0); // 0 = The top of the stack. 

    if(IsCommandDoneSending(0)) 
    { 
      RemoveCommandFromStack(0); 
    } 
} 

人幫助我或給我一些關於如何使這個機制工作的指針。或者另一種可能導致與我試圖實現的工作流相同或相似的方法。

Tks提前!

[更新]

我開始閱讀旗語和它到底似乎這就是我所需要的...但它似乎並不工作...這是林在做僞代碼:

sem_t mutex; 

int stack_count; 

command *stack; 

main() 
{ 
    // Init & Connect client. 

    // Start Thread 

    sem_init(&lock_stack, 0, 1); 

    while(1) 
    { 
     sem_wait(&lock_stack); 

     ++stack_count; 

     stack = (command *) realloc(stack, stack_count * sizeof(command)); 

     strcpy(stack[ stack_count - 1 ].cmd, "new command"); 

     sem_post(&lock_stack); 
    } 
} 


thread() 
{ 
    while(1) 
    { 
     sem_wait(&lock_stack); 

     if(stack_count) 
     { 
      // Send stack[ 0 ].cmd via socket then when done pop the stack like this: 

      --stack_count; 

      if(0 < stack_count) 
      { 
       memcpy(&stack[ 0 ], 
        &stack[ 1 ], 
        (stack_count - 1) * sizeof(command)); 
      }   
     } 

     sem_post(&lock_stack); 
    } 
} 

因爲我基本上是新來的這個,我錯過了一些明顯的東西,因爲我仍然有內存訪問衝突,「似乎」隨機發生在堆棧數組上。

+1

請通過接受一些回答您的問題提高你的接受評級。另外「*我嘗試使用一些標誌,互斥體,但我總是以內存訪問衝突結尾。*」非常含糊。也許你可以提供一些代碼? – Constantinius 2012-03-06 08:27:43

+0

除了計數堆棧條目並允許生產者在沒有條目時等待的信號量之外,還需要使用互斥鎖或CriticalSection保護堆棧免遭多次訪問。另外,爲什麼當初始化信號量計數爲1時,堆棧中最初爲零的項目?哦 - 並試圖通過只堆疊指向動態分配的對象/結構體的指針來擺脫realloc/memcpy的東西。當隊列被互斥鎖鎖定時,堆棧中的realloc/memcpy必須發生,這對爭用不利。 – 2012-03-06 14:57:30

回答

0

一個簡單的解決方案將是:

Thread 1 : 
     lock mutex 
     put items on stack 
     unlock mutex 


    Thread 2 : 
    loop 
     lock mutex 
     check item on stack 
     if somthing get item on stack 
     unlock mutex 

一個更有效的soultion將是:

Thread 1 : 
     lock mutex 
     put items on stack 
     signal on conditionVariable 
     unlock mutex 

Thread 2 : 
     lock mutex 
     check item on stack 
     if none wait on conditionVariable 
     // here you will be woke up when there is a signal 
     get item on the stack 
     unlock mutex 
     do your work 
+0

更有效的解決方案包含死鎖,當線程2等待條件變量時,線程1無法發出信號,因爲它無法獲取互斥鎖。您需要在等待條件變量時臨時釋放線程2中的互斥鎖。 – smerlin 2012-03-06 10:02:34

+0

是的,真的應該有兩個互斥體。一個用於條件變量,一個用於消費者之間的同步。 – UmNyobe 2012-03-06 15:05:29

+0

@smerlin:假設使用pthread條件變量API,等待API被設計爲在持有互斥體時被調用(它在阻塞線程之前的適當時間解鎖它)。事實上,調用'pthread_cond_wait()'而不*保持互斥體時是錯誤的。 – 2012-03-06 20:20:59