2013-11-18 2 views
1

У меня есть программа qt. У меня есть CAN-запросы, которые я хочу отправить в последовательном порядке. Я хочу дождаться ответов, прежде чем отправлять другие запросы.Qt как сделать блокировку ждать до получения данных

SendReadLatchCommand(fam,prod,addr,0x00000000, 4); // 1st request 

// wait for answer and analyze it?? 

SendReadLatchCommand(fam,prod,addr,0x00000002, 4); // 2nd request 

У меня есть метод в receiveData(), называемом моей резьбой приема, где я сохранить полученное сообщение.

Я хочу спать в своей основной программе, и мы пробуждаемся при получении ответа.

Я не могу использовать сигнал/слот, потому что в слоте я не знаю, что такое последний запрос, который я отправил, поэтому я не могу продолжать выдавать запросы.

Как я могу это сделать? спасибо

+1

waitForReadData(), но на самом деле пытаются извлечь его в слот, один путь с QStateMachines (если немного избыточна) –

ответ

0

я не уверен, является ли это хорошая идея, чтобы заблокировать ваш основной поток, однако это может быть сделано с помощью двоичный семафор, который является таким же, как счетный семафор с maxCount 1. Поэтому можно использовать счетный семафор QSemaphore

Как правило, QSemaphore реализуется с точки зрения QWaitCondition (см. справку Qt). Можно блокировать условие ожидания, пока нить CAN не сообщит о состоянии ожидания. Можно скрыть блокировку на ожидание позади некоторого интерфейса, например:

//--- Very simple implementation - concept only 

QWaitCondition cond_; 
QMutex mutex_; 

void rxThreadHandler(/*args*/) 
{ 
    while(!quitCalled()) 
    { 
    waitOnReceivedData();//Blocks, I assume... 
    handleReceivedData(); 
    answerRxd(); 
    } 
} 

void answerRxd() 
{ 
    QMutexLocker lock(mutex_); 
    cond_.wakeAll(); 
} 

void sendNext(const Buffer& buffer) 
{ 
    QMutexLocker guard(mutex_); 
    //Waits/Blocks until condition signalled, then locks mutex 
    // to prevent further signalling (might block rx thread) 
    cond_.wait(lock.mutex()); 
    //Unlocking mutex explicitly to allow receipt of data 
    guard.unlock(); 
    //Now send as result of previous receive. This does not 
    // prevent receiving thread...  
    sendNextImpl(const Buffer& buffer); 
} 
+0

Хотя QSemaphore примечателен, Я считаю QEventLoop лучшей конструкцией для этой цели. QSemaphore может быть расширен для создания архитектуры производителя/потребителя, где поток ожидания становится потребителем. Я реализовал такую ​​архитектуру, которая производит обратные вызовы, которые выполняются потребителем, но код обширен. –

+0

В ретроспективе я считаю, что для этого достаточно обычного условного ожидания за правильным интерфейсом. EventLoop может быть излишним, но я пока не могу понять, почему это не может быть решением. –

+0

Мне нравится ваше решение, но я попробовал QWaitCondition, и он блокирует поток приема, поскольку он получает много других сообщений, кажется, что невозможно заблокировать поток. Итак, я буду реализовывать своего рода секвенсор. Я сохраняю последнее отправленное сообщение и анализирую ответы на приеме. – user3004111

2

Если я вас правильно понимаю, вы хотели обработать запрос синхронно.

Посмотрите в QEventLoop в qtdoc, вы можете сделать это следующим образом:

QEventLoop wait_loop; 
// 1st request 
connect(request_1, SIGNAL(sig_answer_arrived()), &wait_loop, SLOT(quit())); 
request_1->send_request(); 
wait_loop.exec(); 
// here we already got the answer 
analyze_answer(); 

// the 2nd request does the same 
+0

я не знаю QEventLoop, но я думаю, что это не проблема. мои запросы и ответы синхронны. Я хочу загрузить файл на далекий борд. поэтому я должен читать адреса, отправлять блоки. После каждого запроса я жду ответа, я анализирую его, если он поврежден, я отправляю его снова. Поэтому я хотел, чтобы мой основной поток ожидал ответа. Потому что, если я получаю ответ другим способом, трудно узнать, что последний запрос отправлен. Но я попытаюсь сохранить последнее состояние как конечный автомат и извлечь анализ данных в слот. – user3004111

Смежные вопросы