C++11的std::thread
在C中已经有一个叫做pthread的东西来进行多线程编程,但是并不好用 (如果你认为句柄、回调式编程很实用,那请当我没说),所以c++11标准库中出现了一个叫作std::thread的东西。
std::thread常用成员函数
构造&析构函数
举个栗子
例一:thread的基本使用
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 using namespace std; 6 void doit() { cout << "World!" << endl; } 7 int main() { 8 // 这里的线程a使用了 C++11标准新增的lambda函数 9 // 有关lambda的语法,请参考我之前的一篇博客 10 // https://blog.csdn.net/sjc_0910/article/details/109230162 11 thread a([]{ 12 cout << "Hello, " << flush; 13 }), b(doit); 14 a.join(); 15 b.join(); 16 return 0; 17 }
那么,为什么会有不同的结果呢?
这就是多线程的特色!
多线程运行时是以异步方式执行的,与我们平时写的同步方式不同。异步方式可以同时执行多条语句。
在上面的例子中,我们定义了2个thread,这2个thread在执行时并不会按照一定的顺序。打个比方,2个thread执行时,就好比赛跑,谁先跑到终点,谁就先执行完毕。
例二:thread执行有参数的函数
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 using namespace std; 6 void countnumber(int id, unsigned int n) { 7 for (unsigned int i = 1; i <= n; i++); 8 cout << "Thread " << id << " finished!" << endl; 9 } 10 int main() { 11 thread th[10]; 12 for (int i = 0; i < 10; i++) 13 th[i] = thread(countnumber, i, 100000000); 14 for (int i = 0; i < 10; i++) 15 th[i].join(); 16 return 0; 17 }
注意:我说的是有可能。你的运行结果可能和我的不一样,这是正常现象,在上一个例子中我们分析过原因。
这个例子中我们在创建线程时向函数传递了一些参数,但如果要传递引用参数呢?是不是像这个例子中直接传递就行了?
让我们来看看第三个例子:
例三:thread执行带有引用参数的函数
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 using namespace std; 6 template<class T> void changevalue(T &x, T val) { 7 x = val; 8 } 9 int main() { 10 thread th[100]; 11 int nums[100]; 12 for (int i = 0; i < 100; i++) 13 th[i] = thread(changevalue<int>, nums[i], i+1); 14 for (int i = 0; i < 100; i++) { 15 th[i].join(); 16 cout << nums[i] << endl; 17 } 18 return 0; 19 }
如果你尝试编译这个程序,那你的编译器一定会报错
这是怎么回事呢?原来thread在传递参数时,是以右值传递的:
// Compiler: MSVC 19.29.30038.1 // C++ Standard: C++17 #include <iostream> #include <thread> using namespace std; template<class T> void changevalue(T &x, T val) { x = val; } int main() { thread th[100]; int nums[100]; for (int i = 0; i < 100; i++) th[i] = thread(changevalue<int>, ref(nums[i]), i+1); for (int i = 0; i < 100; i++) { th[i].join(); cout << nums[i] << endl; } return 0; }
这次编译可以成功通过,你的程序输出的结果应该是这样的:
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 using namespace std; 6 int n = 0; 7 void count10000() { 8 for (int i = 1; i <= 10000; i++) 9 n++; 10 } 11 int main() { 12 thread th[100]; 13 // 这里偷了一下懒,用了c++11的foreach结构 14 for (thread &x : th) 15 x = thread(count10000); 16 for (thread &x : th) 17 x.join(); 18 cout << n << endl; 19 return 0; 20 }
例四:std::mutex的使用
// Compiler: MSVC 19.29.30038.1 // C++ Standard: C++17 #include <iostream> #include <thread> #include <mutex> using namespace std; int n = 0; mutex mtx; void count10000() { for (int i = 1; i <= 10000; i++) { mtx.lock(); n++; mtx.unlock(); } } int main() { thread th[100]; for (thread &x : th) x = thread(count10000); for (thread &x : th) x.join(); cout << n << endl; return 0; }
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 // #include <mutex> //这个例子不需要mutex了 6 #include <atomic> 7 using namespace std; 8 atomic_int n = 0; 9 void count10000() { 10 for (int i = 1; i <= 10000; i++) { 11 n++; 12 } 13 } 14 int main() { 15 thread th[100]; 16 for (thread &x : th) 17 x = thread(count10000); 18 for (thread &x : th) 19 x.join(); 20 cout << n << endl; 21 return 0; 22 }
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 #include <future> 6 using namespace std; 7 int main() { 8 async(launch::async, [](const char *message){ 9 cout << message << flush; 10 }, "Hello, "); 11 cout << "World!" << endl; 12 return 0; 13 }
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 // #include <thread> // 这里我们用async创建线程 5 #include <future> // std::async std::future 6 using namespace std; 7 8 template<class ... Args> decltype(auto) sum(Args&&... args) { 9 // C++17折叠表达式 10 // "0 +"避免空参数包错误 11 return (0 + ... + args); 12 } 13 14 int main() { 15 // 注:这里不能只写函数名sum,必须带模板参数 16 future<int> val = async(launch::async, sum<int, int, int>, 1, 10, 100); 17 // future::get() 阻塞等待线程结束并获得返回值 18 cout << val.get() << endl; 19 return 0; 20 }
例八:void特化std::future
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <future> 5 using namespace std; 6 void count_big_number() { 7 // C++14标准中,可以在数字中间加上单 8 // 引号 ' 来分隔数字,使其可读性更强 9 for (int i = 0; i <= 10'0000'0000; i++); 10 } 11 int main() { 12 future<void> fut = async(launch::async, count_big_number); 13 cout << "Please wait" << flush; 14 // 每次等待1秒 15 while (fut.wait_for(chrono::seconds(1)) != future_status::ready) 16 cout << '.' << flush; 17 cout << endl << "Finished!" << endl; 18 return 0; 19 }
// Compiler: MSVC 19.29.30038.1 // C++ Standard: C++17 #include <iostream> using namespace std; constexpr long double PI = 3.14159265358979323846264338327950288419716939937510582097494459230781640628; // 给定圆的半径r,求圆的直径、周长及面积 void get_circle_info(double r, double &d, double &c, double &s) { d = r * 2; c = PI * d; s = PI * r * r; } int main() { double r; cin >> r; double d, c, s; get_circle_info(r, d, c, s); cout << d << ' ' << c << ' ' << s << endl; return 0; }
例十一:std::promise的使用
以例七中的代码为基础加以修改:
1 // Compiler: MSVC 19.29.30038.1 2 // C++ Standard: C++17 3 #include <iostream> 4 #include <thread> 5 #include <future> // std::promise std::future 6 using namespace std; 7 8 template<class ... Args> decltype(auto) sum(Args&&... args) { 9 return (0 + ... + args); 10 } 11 12 template<class ... Args> void sum_thread(promise<long long> &val, Args&&... args) { 13 val.set_value(sum(args...)); 14 } 15 16 int main() { 17 promise<long long> sum_value; 18 thread get_sum(sum_thread<int, int, int>, ref(sum_value), 1, 10, 100); 19 cout << sum_value.get_future().get() << endl; 20 get_sum.join(); // 感谢评论区 未来想做游戏 的提醒 21 return 0; 22 }
1 #include <iostream> 2 #include <thread> 3 #include <atomic> 4 using namespace std; 5 atomic_bool ready = 0; 6 // uintmax_t ==> unsigned long long 7 void sleep(uintmax_t ms) { 8 this_thread::sleep_for(chrono::milliseconds(ms)); 9 } 10 void count() { 11 while (!ready) this_thread::yield(); 12 for (int i = 0; i <= 20'0000'0000; i++); 13 cout << "Thread " << this_thread::get_id() << " finished!" << endl; 14 return; 15 } 16 int main() { 17 thread th[10]; 18 for (int i = 0; i < 10; i++) 19 th[i] = thread(::count); 20 sleep(5000); 21 ready = true; 22 cout << "Start!" << endl; 23 for (int i = 0; i < 10; i++) 24 th[i].join(); 25 return 0; 26 }
转自:https://blog.csdn.net/sjc_0910/article/details/118861539
标签:11,std,include,17,thread,int,C++,多线程 From: https://www.cnblogs.com/Jack-Elvis/p/17854076.html