Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A toy program on how to use some C++0x threading and synchronization facilities. No idea on what the performance of this (I recommend Matt's answer), my focus is on clarity and correctness for the sake of making an example.</p> <p>The files are read separately, as you requested. They're not converted to a sequence of <code>int</code> however, as I feel this is more related to processing rather than strict I/O. So the files are dumped into a plain <code>std::string</code>.</p> <pre><code>#include &lt;fstream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;vector&gt; #include &lt;deque&gt; #include &lt;future&gt; #include &lt;mutex&gt; #include &lt;condition_variable&gt; int main() { // this is shared std::mutex mutex; std::condition_variable condition; bool more_to_process = true; std::deque&lt;std::string&gt; to_process; /* Reading the files is done asynchronously */ std::vector&lt;std::string&gt; filenames = /* initialize */ auto process = std::async(std::launch::async, [&amp;](std::vector&lt;std::string&gt; filenames) { typedef std::lock_guard&lt;std::mutex&gt; lock_type; for(auto&amp;&amp; filename: filenames) { std::ifstream file(filename); if(file) { std::ostringstream stream; stream &lt;&lt; file.rdbuf(); if(stream) { lock_type lock(mutex); to_process.push_back(stream.str()); condition.notify_one(); } } } lock_type lock(mutex); more_to_process = false; condition.notify_one(); }, std::move(filenames)); /* processing is synchronous */ for(;;) { std::string file; { std::unique_lock&lt;std::mutex&gt; lock(mutex); condition.wait(lock, [&amp;] { return !more_to_process || !to_process.empty(); }); if(!more_to_process &amp;&amp; to_process.empty()) break; else if(to_process.empty()) continue; file = std::move(to_process.front()); to_process.pop_front(); } // use file here } process.get(); } </code></pre> <p>Some notes:</p> <ul> <li>the mutex, condition variable, stop flag and <code>std::string</code> container are all logically related. You may as well replace them with a thread-safe container/channel</li> <li>I use <code>std::async</code> instead of <code>std::thread</code> because it has better exception-safety characteristics</li> <li>there is no error handling to speak of; if a file can't be read for some reason, it is silently skipped. You have several options: signal that there is no more to process and throw to handle as soon as possible; or use a <code>boost::variant&lt;std::string, std::exception_ptr&gt;</code> to pass the error on to the processing side of things (here the error is passed as an exception but you can use an <code>error_code</code> or anything you fancy). Not an exhaustive list by any means.</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload