1. Introduction to C ++ 0X Multithreading
C ++ 0x STL provides multi-threaded support, so you don't have to choose a cross-platform multi-threaded library. Use the standard one :)
I have checked that BOOST is almost identical with the current STL interface. :) That is to say, the program written with boost thread should include boost: thread, boost: unique_lock... replace it with std: thread, std: unique_lock... I think, but I have never used boost thread. so those familiar with pthread should be able to get started quickly, while those familiar with boost thread can get started directly ~
But now GCC does not support the thread local variable. Atomic operations are not supported. Basic mutex and condional variables are supported.
For more information about C ++ 0X thread, see:
Simpler Multithreading in C ++ 0x
Http://www.devx.com/SpecialReports/Article/38883/0/page/1
This document has a Chinese Translation
Overview of C ++ 0x: multithreading (1)-VC ++-upwind
Www.upwinder.com/www/c1/2999.html
Multithreading in C ++ 0x
Http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-1-starting-threads.html
[Translation] discard the original thread API and use the new C ++ thread
Www.cppprog.com/2009/0102/30.html
In addition, if you use C ++ 0X, you 'd better understand the so-called right value reference and move semantics. I personally think these two concepts are very useful and are a breakthrough concept, you can also use thread. refer to the C ++ 0x series written by Liu weipeng: Right Value reference (or "move semantics and perfect forwarding") (on ).
Http://blog.csdn.net/pongba/archive/2007/07/10/1684519.aspx
Or see A Brief Introduction to Rvalue References http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html
2. How to compile and run
I only tried GCC4.4.2 in linux. Debugging is successful.
First, make sure that your GCC compilation is thread enable. Generally, the default installation is enable. You can use gcc-v to View Details:
Allen :~ /Study/unix_system/CH14 $ gcc-v
Use built-in specs.
Goals: i686-pc-linux-gnu
Configuration: ../configure
Thread model: posix
Gcc 4.4.2 (GCC)
The preceding display thread model posix indicates that multiple threads can be used. Otherwise, the display is empty. Note that it is posix multithreading in essence, so you need to add the compilation parameter-pthread
It also indicates the use of the c ++ 0x feature,-std = c ++ 0x or-std = gnu0x
For example:
G ++-g-o wordcount. cc-std = c ++ 0x-pthread
3. A complete small program example, multi-threaded text word count statistics
First, let's talk about the purpose of the program. Each thread counts the number of words in one text. As an experiment program, here is an example of three thread statistics. This example involves thread synchronization, because after each thread completes statistics, it reports to the main thread that it has completed statistics and writes the information to the mail_box In the mutex zone. The main thread reads the information from mail_box, and then notifies the next thread to write mail_box. that is to say, when three statistical word threads are regarded as writers and the main thread is regarded as readers, only one thread can access mail_box reading or writing at a time.
The source of this problem is the example of the twocount4.c section in the unix programming practice tutorial p14.5.2 using conditional variables to write programs. pthread is used in the original article, but it is problematic, the example in the book is two threads responsible for statistics. Expansion to three will lead to deadlocks, mainly because the example in the book only uses one conditional variable and does not distinguish between reader notifications and writer notifications. I have written an article to analyze this situation multithreading synchronization problem conditional variables and semaphore http://www.cnblogs.com/rocketfan/archive/2009/07/24/1530477.html
At that time, I did not understand the conditional variables very clearly, so I wrote a correct version using semaphores. In fact, mutex + conditional variables can solve all problems that can be solved by the signal volume. However, I still don't know why c ++ 0x STL does not provide semaphores. boost threads are not provided, but exist in the boost interprocess library. It seems that the semaphores are not used for multithreading, why? Who should explain it to me in detail? Thank you. It is true that conditional variables are more powerful, but I always think that semaphores are clearer. The operating system textbooks also use semaphores for example. For example, the operating system kernel settings and design principles. For example, this problem can be expressed as follows using semaphores. Of course, the conditional variables are similar:
Write = 0
Read = 0
Mail = null
// Server main thread
V (read) // to let one client sub thread can write at first since mail = null
For (I = 0; I <sub threads num; I ++)
P (write)
Read mail
Mail = null
V (read)
// Clinent sub threads
P (read)
Write mail
V (write)
The implementation of C ++ 0X, mutex + conditional variable is as follows, with detailed annotations. If you have any questions, please correct them:
Code
/**
*
*
* \ File wordcount. cc
*
* \ Author chenghuige@gmail.com
*
* \ Date 09:55:25. 197674
*
* Description: demonstrates the use of c ++ 0x, mutex, and condition variables after the thread is established. Note that for simple names
* Std ::
*
*/
# Include
# Include
# Include
# Include
Using namespace std;
Mutex m;
Condition_variable reader_cond; // cond notify reader
Condition_variable writer_cond; // cond2 using Y writer
Struct MailBox {
String file_name; // which file
Int count; // how many words
Int tid; // which thread write
};
MailBox mail_box;
Class WordCounter
{
Private:
Int tid _;
String infile_name _;
Public:
WordCounter (int tid, string infile_name ):
Tid _ (tid), infile_name _ (infile_name ){}
Void operator ()(){
Int c, prevc = '\ 0 ';
Int count = 0;
// Count the number of words in the text
Ifstream input_file (infile_name _. c_str (), ios: binary );
Input_file.unsetf (ios: skipws); // a space character is required.
Istreambuf_iterator eos; // end-of-range iterator
Istreambuf_iterator iit (input_file );
For (; iit! = Eos; ++ iit ){
C = * iit;
If (! Isalnum (c) & isalnum (prevc ))
Count ++;
Prevc = c;
}
Input_file.close ();
Cout <"COUNT" <tid _ <"waiting to get lock" <endl;
Unique_lock lk (m );
Cout <"COUNT" <tid _ <"have lock, store data" <endl;
// If mail_box is not empty, note that mail_box is protected by the mutex.
While (! Mail_box.file_name.empty ()){
Cout <"COUNT" <tid _ <"oops.. mail box not empty, wait for signal" <endl;
// Wait for the reader to finish reading and notice, and write the release lock Control
Writer_cond.wait (lk); // note that wait only accepts unique_lock and does not accept lock_guard
// Re-lock the mutex
}
Cout <"COUNT" <tid _ <"OK, I can write mail" <endl;
Mail_box.file_name = infile_name _;
Mail_box.count = count;
Mail_box.tid = tid _;
Cout <"COUNT" <tid _ <"rasing flag" <endl;
// Notify the reader that I have finished writing and you can read it.
Reader_cond.policy_one ();
// Note that I still have a lock here, so even though the reader has borrowed a readable notification, it will still be stuck out of the mutex zone.
Cout <"COUNT" <tid _ <"Finished writting. Words are" <count <"for file"
<Infile_name _ <endl;
Cout <"COUNT" <tid _ <"will unlock" <endl;
// At the end, lk's destructor will automatically call the unlock function. Note that this is not necessarily because the reader can obtain the mutex. It is possible that
// It doesn't matter if other writers get it first. They find that mail_box is not empty and wait will release the mutex, so it is possible
// The following occurs:
// COUNT 0 will unlock
// COUNT 1 have lock, store data
// COUNT 1 oops .. mail box not empty, wait for signal
// COUNT 2 have lock, store data
// COUNT 2 oops.. mail box not empty, wait for signal
// MAIN: Wow! Flag was raised, I have the lock
// 11 1.log 0
// Main has finished reading
}
};
Void read_mail (char * argv [])
{
// The reader must first lock the mutex
Unique_lock lk (m );
Cout <"Main locking the box" <endl;
// Create three threads. Note that empty threads are created here,
// Then, with the move of the temporary variable, the thread cannot copy but can move
Thread t [3];
For (int I = 0; I <3; I ++)
T [I] = thread (WordCounter (I, argv [I + 1]);
Int total_words = 0;
// The reader needs to wait for three writers to finish collecting the text information
For (int reports_in = 0; reports_in <3; reports_in ++ ){
Cout <"MAIN: waiting for flag to go up" <endl;
// Wait for a writer to write the mail and release the specified lock m.
Reader_cond.wait (lk );
// Receives the signal written by the writer. The reader can read it and lock the mutex.
Cout <"MAIN: Wow! Flag was raised, I have the lock "<endl;
Cout <mail_box.count <"" <mail_box.file_name <"" <mail_box.tid <endl;
Total_words + = mail_box.count;
// After reading the message, the reader will leave the mail_box file name blank, indicating that the file has been read.
Mail_box.file_name.clear ();
Cout <"Main has finished reading" <endl;
// Notification writer I have read the mail box
Writer_cond.policy_one ();
}
For (int I = 0; I <3; I ++ ){
T [I]. join ();
}
Cout <total_words <": total words" <endl;
}
Int main (int argc, char * argv [])
{
If (argc! = 4 ){
Cout <"usage:" <argv [0] <"file1 file2 file3" <endl;
Exit (1 );
}
Read_mail (argv );
}
Running result
Main locking the box
COUNT 0 waiting to get lock
COUNT 1 waiting to get lock
COUNT 2 waiting to get lock
MAIN: waiting for flag to go up
COUNT 0 have lock, store data
COUNT 0 OK, I can write mail
COUNT 0 rasing flag
COUNT 0 Finished writting. Words are 11 for file 1.log
COUNT 0 will unlock
COUNT 1 have lock, store data
COUNT 1 oops .. mail box not empty, wait for signal
COUNT 2 have lock, store data
COUNT 2 oops .. mail box not empty, wait for signal
MAIN: Wow! Flag was raised, I have the lock
11 1.log 0
Main has finished reading
MAIN: waiting for flag to go up
COUNT 1 OK, I can write mail
COUNT 1 rasing flag
COUNT 1 Finished writting. Words are 128 for file twordcount1.c
COUNT 1 will unlock
MAIN: Wow! Flag was raised, I have the lock
128 twordcount1.c 1
Main has finished reading
MAIN: waiting for flag to go up
COUNT 2 OK, I can write mail
COUNT 2 rasing flag
COUNT 2 Finished writting. Words are 382 for file twordcount4_semaphore.c
COUNT 2 will unlock
MAIN: Wow! Flag was raised, I have the lock
382 twordcount4_semaphore.c 2
Main has finished reading
521: total words