2012-03-06 86 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