Синхронизация стеков между потоками - PullRequest
0 голосов
/ 06 марта 2012

Я работаю на клиенте (который использует графический интерфейс и сокет). Графический интерфейс (работающий в основном потоке) создает на лету команды моего протокола, каждый раз, когда я создаю новую команду, я добавляю ее в динамический стек.

В другом потоке (использующем pthread) я проверяю, есть ли команда в стеке, затем постепенно отправляю ее, используя сокет (который не является блоком между прочим). Когда команда в верхней части стека завершена, я отправляю стек (это означает, что команда удалена, и каждая команда, расположенная ниже первого элемента, перемещается вверх).

Теперь, как вы можете догадаться, у меня огромные проблемы с синхронизацией ... Я пытаюсь использовать некоторые флаги, мьютекс, но всегда получаю некоторое нарушение доступа к памяти.

В основном то, что я делаю, это:

В основной теме, когда (то есть) пользователь нажимает кнопку:

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

AppendCommandToSendStack( cmd );

В другой теме:

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

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

Кто-нибудь может мне помочь или дать несколько советов о том, как заставить этот механизм работать. Или другой подход, который привел бы к тому же или аналогичному рабочему процессу, который я пытаюсь реализовать.

ТКС заранее!

[Обновить]

Я начинаю читать на семафоре, и мне кажется, что это именно то, что мне нужно ... однако, похоже, это не работает ... это то, что я делаю в псевдокоде:

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 );
    }
}

Поскольку я в основном новичок в этом, я упускаю что-то очевидное, потому что у меня все еще есть нарушение доступа к памяти, которое "кажется" происходит случайно в массиве стека.

Ответы [ 2 ]

2 голосов
/ 06 марта 2012

У вас есть классический пример проблемы производитель-потребитель.Вы хотите produce команды, в то время как другие темы consume их.Вы можете взглянуть на http://en.wikipedia.org/wiki/Producer-consumer_problem, который объясняет, как реализовать основную проблему производителя-потребителя.

0 голосов
/ 06 марта 2012

Простое решение будет:

 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

Более эффективной душой будет:

 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...