The second error that we will fix in the example code is that the printing from the two threads may become interleaved. The program is intended to print one line of 50 question marks and to print line of 50 exclamation points. But when the functions funct1 and funct2 are converted into threads, and when the main program is changed to wait on the threads to finish, then the question marks and the exclamation points can become interleaved. The function version of the program prints all 50 question marks before printing any of the exclamation points. The threaded version of the program does not attempt to control whether the question marks or the exclamation points print first. But it is the case either that all the question marks should print before any of the exclamation points, or vice versa. |
The solution for the print interleaving problem is a mutex. A mutex is a locking mechanism that enables two or more threads to serialize a portion of their processing. In this case, the printing will be serialized so that only one of the two threads can be printing at the same time. One purpose for threads is that multiple threads can be executing at the same time, which is most efficacious when there are multiple processor cores available so that the threads can truly be running in parallel. In a sense, the use of mutexes can defeat temporarily the parallel processing that is one of the chief purposes for using threads. Nevertheless, judicious use of mutexes is nearly always required with threads to protect sections of code that have to be serialized. Even though a mutex is a locking mechanism, I don't want to call a mutex a lock because there is something else very akin to a mutex that we are soon going to be calling a lock. So we will just call a mutex a mutex, and if that seems a bit circular, then so be it. |
#include "stdafx.h" #include <iostream> #include <boost/thread.hpp> void funct1(); void funct2(); boost::mutex zzzz; int main() { boost::thread xxxx(funct1); boost::thread yyyy(funct2); xxxx.join(); yyyy.join(); return 0; } void funct1() { zzzz.lock(); for (int i = 0; i < 50; i++) std::cout << '?'; std::cout << std::endl; zzzz.unlock(); } void funct2() { zzzz.lock(); for (int i = 0; i < 50; i++) std::cout << '!'; std::cout << std::endl; zzzz.unlock(); } |
|
This page last edited on 26 Mar 2016.