I have a program that uploads data to a server in another thread (std::thread
). I would like to monitor the progress of the data transfer using some atomic doubles. The client writes data like this (for full disclosure I didn't remove the write
calls):
setUploadProgress(0,static_cast<double>(message.size()));
while(static_cast<long>(message.size()) - count >= max_length)
{
boost::asio::write(socket_,
boost::asio::buffer(message.substr(count,max_length)));
count += max_length;
setUploadProgress(static_cast<double>(count),static_cast<double>(message.size()));
}
boost::asio::write(socket_,boost::asio::buffer(message.substr(count,max_length)),boost::asio::transfer_at_least(static_cast<long>(message.size()) - count),error);
setUploadProgress(static_cast<double>(message.size()),static_cast<double>(message.size()));
handle_write(error);
This will write max_length
at a time, and update the progress variables. setUploadProgress
looks like this:
void SSLClient::setUploadProgress(double uploadedSize, double totalSize)
{
std::lock_guard<decltype(this->progress_mutex)> lg(this->progress_mutex);
if(this->progressValue_uploaded != nullptr) this->progressValue_uploaded->store(uploadedSize);
if(this->progressValue_uploadTotalSize != nullptr) this->progressValue_uploadTotalSize->store(totalSize);
}
The following is how I capture the upload progress:
auto resultFuture = fileToUpload.promise.get_future();
commThreadController->uploadFile(&fileToUpload);
while (resultFuture.wait_for(std::chrono::milliseconds(10)) != std::future_status::ready)
{
std::cerr<<fileToUpload.getProgress()*100.<<"%"<<std::endl;
QCoreApplication::processEvents();
}
uploadFinished(resultFuture.get(),fileToUpload);
And this is how fileToUpload.getProgress()
looks like:
double FileToUpload::getProgress() const
{
return progressValue_uploaded.load()/progressValue_uploadTotalSize.load();
}
The problem: I can see that the value of the progress is updated very often (by simply cout
ing the progress value on every update), for a specific case I've been studying, up to about every 0.1%. However, on the main thread, I see the change only every 3%! What synchronization option should I be using to make this fast that every update can be seen in the main thread? By default everything is synchronized with memory_order_seq_cst
(which is basically the best sync I know of), but that doesn't seem to be enough! What am I missing?
Aucun commentaire:
Enregistrer un commentaire