参照渡し後にclient.cpp内のdata_received
ベクターをクリアするとき、未定義の振る舞いを扱っていたのか不思議です。私は無効なデータで問題が発生したことはありませんしかし、これはどこに問題があるかもしれないか分かります潜んでいます。 vector
は最後のキューに参照渡しされています。一方、もう1つのスレッドはqueue_event.notify_all()
が起動した後にのみ独自のレートでデキューされます。参照でベクターを渡してから呼び出しをクリアする
この問題が発生した場合は、のクライアントのの受信をブロックした直後に解決策が明らかになっていると思います。思考?
blocking_queue.h
template <typename T>
class BlockingQueue {
...
std::queue<T> queue;
...
};
blocking_queue.cpp
template <class T>
void BlockingQueue<T>::enqueue(T const &item)
{
std::unique_lock<std::mutex> lk (queue_lock);
queue.push(item);
lk.unlock();
queue_event.notify_all();
}
template <class T>
T BlockingQueue<T>::dequeue()
{
std::unique_lock<std::mutex> lk (queue_lock);
if(queue_event.wait_for(lk, std::chrono::milliseconds(dequeue_timeout)) == std::cv_status::no_timeout)
{
T rval = queue.front();
queue.pop();
return rval;
}
else
{
throw std::runtime_error("dequeue timeout");
}
}
client.cpp
void Client::read_from_server()
{
std::vector<uint8_t> data_received;
while(run)
{
if (client->is_connected())
{
uint8_t buf[MAX_SERVER_BUFFER_SIZE];
int returned;
memset(buf, 0, MAX_SERVER_BUFFER_SIZE);
returned = client->receive(client->get_socket_descriptor(), buf, MAX_SERVER_BUFFER_SIZE);
// should probably move data_received.clear() to here!!
if (returned > 0)
{
for (int i = 0; i < returned; i++)
{
data_received.push_back(buf[i]);
}
if (incoming_queue)
{
incoming_queue->enqueue(data_received);
}
data_received.clear();
}
else
{
client->set_connected(false);
}
}
}
}
ahhhは、voidのstd :: queue push(const value_type & val);? – atomSmasher
@atomSmasher)のためのものです。実際には 'const'についてはそうではありません。値のコピーとして初期化される](http://en.cppreference.com/w/cpp/container/list/push_back)(値が一時的であるか、コンパイラが値の状態があなたのケースでは 'T'は'ベクトル 'なのでコピーまたは移動されますが、後でそれをクリアすることは問題ありません。実際に' container 'は' T 'が渡されたTのコピーや移動を行います。' T'がポインタ型のときは心配する必要があります。 –
wow。正しいです。 – atomSmasher