편집 : 아래생산자 - 소비자 시나리오에서 부스트 조건 변수를 어떻게 사용할 수 있습니까?
버퍼의 장치에서 데이터를 스트리밍하는 스레드가 하나 있습니다. 또한, 그 데이터에 대한 처리를 N 개의 스레드가 있습니다. 설치 과정에서 스 트리머 스레드가 장치에서 데이터를 가져오고 새 데이터를 페치하거나 제한 시간에 도달하기 전에 N 스레드가 처리를 마칠 때까지 기다려야합니다. N 스레드는 처리를 계속하기 전에 새 데이터를 가져올 때까지 대기해야합니다. 나는이 프레임 워크가 N 스레드가 버퍼에서 프로세싱을 반복하는 것을 원하지 않는다면 모든 버퍼가 건너 뛰지 않고 처리되기를 원한다면 작동해야한다고 생각한다.
주의 깊게 읽은 후에 조건 변수가 필요한 것임을 알았습니다. 나는 자습서 및 다른 스택 오버플로 질문을 따랐다, 이것은 내가 무엇을 가지고 :
전역 변수 :
boost::condition_variable cond;
boost::mutex mut;
멤버 변수 :
이std::vector<double> buffer
std::vector<bool> data_ready // Size equal to number of threads
데이터 수신기 루프 (1 개 실이 실행을) :
while (!gotExitSignal())
{
{
boost::unique_lock<boost::mutex> ll(mut);
while(any(data_ready))
cond.wait(ll);
}
receive_data(buffer);
{
boost::lock_guard<boost::mutex> ll(mut);
set_true(data_ready);
}
cond.notify_all();
}
데이터 처리 루프 (N 개의 스레드에서 실행)
while (!gotExitSignal())
{
{
boost::unique_lock<boost::mutex> ll(mut);
while(!data_ready[thread_id])
cond.wait(ll);
}
process_data(buffer);
{
boost::lock_guard<boost::mutex> ll(mut);
data_ready[thread_id] = false;
}
cond.notify_all();
}
이 두 루프는 같은 클래스의 자체 멤버 함수에 있습니다. 가변 버퍼는 멤버 변수이므로 스레드간에 공유 될 수 있습니다.
수신 스레드가 먼저 실행됩니다. data_ready 변수는 크기가 N 인 bool의 벡터입니다. data_ready [i]는 데이터를 처리 할 준비가되면 true이고, 스레드가 이미 데이터를 처리 한 경우 false입니다. any (data_ready) 함수는 data_ready의 요소 중 하나가 true이면 true를 출력하고 그렇지 않으면 false를 출력합니다. set_true (data_ready) 함수는 data_ready의 모든 요소를 true로 설정합니다. 수신 쓰레드는 처리중인 쓰레드가 여전히 처리 중인지 확인합니다. 그렇지 않다면, 데이터를 가져오고, data_ready 플래그를 설정하고, 스레드에 알리고, 처리가 완료 될 때까지 시작 부분에서 멈출 루프를 계속할 것입니다. 처리 스레드는 각각의 data_ready 플래그가 true인지 확인합니다. 일단 그것이 사실이면, 처리 스레드는 일부 계산을 수행하고, 각각의 data_ready 플래그를 0으로 설정하고, 루프를 계속할 것이다.
처리 스레드가 하나 뿐인 경우 프로그램이 정상적으로 실행됩니다. 더 많은 스레드를 추가하고 나면 처리 결과가 불필요한 문제가 발생합니다. 또한 처리 스레드의 순서는 어떤 이유로 중요합니다. 다시 말하면, 내가 시작한 LAST 스레드는 올바른 데이터를 출력하지만, 입력 매개 변수가 처리에 관계없이 (유효한 매개 변수를 가정 할 때) 이전 스레드는 가비지를 출력합니다. 문제가 내 스레딩 코드로 인한 것인지 또는 장치 또는 데이터 처리 설정에 문제가 있는지 알 수 없습니다. I는 처리에 couts을 사용하고 단계를 수신하고, 정상적으로 N 프로세싱 스레드, I 출력 표시보십시오
receive data
process 1
process 2
...
process N
receive data
process 1
process 2
...
는 조건 변수 정확한의 용도는? 무엇이 문제 일 수 있습니까?
편집 : (N 스레드가이 실행)
while (!gotExitSignal())
{
// boost::unique_lock<boost::mutex> ll(mut);
boost::mutex::scoped_lock ll(mut);
cond.wait(ll);
process_data(buffer);
data_ready[thread_id] = false;
}
while (!gotExitSignal())
{
if(!any(data_ready))
{
receive_data(buffer);
boost::lock_guard<boost::mutex> ll(mut);
set_true(data_ready);
cond.notify_all();
}
}
데이터 처리 루프 : 나는 포크의 제안을 따라에 코드를 변경 :
이데이터 수신기 루프 (1 개 실이 실행됩니다)
다소 개선되었습니다. 올바른 잠금 장치를 사용하고 있습니까?
'모든'기능 검사는 무엇입니까? 진실 또는 거짓? – peper0
요소가 true이면 true를 반환합니다. – Damian
'channel_id'와'thread_id'는 같은 id입니다, 맞습니까? 그리고'process_data (buffer);는 오히려'process_data (buffer [thread_id]); process_data와 동일합니까? – peper0