C# 使用正则表达式(dotnetcore)_"regex rx = new regex(@\"
赞
踩
目录
头文件:#include <thread>
(1). 默认构造函数,创建一个空的 thread 执行对象。
(2). 初始化构造函数,创建一个 thread对象,该 thread对象可被 joinable,新产生的线程会调用 fn 函数,该函数的参数由 args 给出。
(3). 拷贝构造函数(被禁用),意味着 thread 不可被拷贝构造。
(4). move 构造函数,move 构造函数,调用成功之后 x 不代表任何 thread 执行对象。
注意:可被 joinable 的 thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached.
一、用函数对象创建线程
二、用类对象创建线程
三、把某个类中的某个函数作为线程的入口地址
四、用lambda表达式创建线程
参考:(1条消息) c++ 多线程(2)创建线程对象的方法_一抹烟霞的博客-CSDN博客_多线程创建对象
- #include <iostream>
- #include <utility>
- #include <thread>
- #include <chrono>
-
- void f1(int n)
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 1 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 1 id = " << std::this_thread::get_id()<< std :: endl ;
- }
-
- void f2(int& n)
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 2 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 2 id = " << std::this_thread::get_id()<< std :: endl ;
- }
-
- class foo
- {
- public:
- void bar(int a)
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 3 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 3 id = " << std::this_thread::get_id()<< std :: endl ;
- std::cout << "a = " << a << std :: endl ;
- }
- void bar2()
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 33 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 33 id = " << std::this_thread::get_id()<< std :: endl ;
- }
- int n = 0;
- };
-
- class baz
- {
- public:
- baz(){std::cout << "I am in" << std :: endl ;}
- void operator()()
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 4 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 4 id = " << std::this_thread::get_id()<< std :: endl ;
- }
- void bar3()
- {
- for (int i = 0; i < 5; ++i) {
- std::cout << "Thread 44 executing\n";
- ++n;
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- std::cout << "Thread 44 id = " << std::this_thread::get_id()<< std :: endl ;
- }
- int n = 0;
- };
-
- int main()
- {
- int n = 0;
- foo f;
- baz b;
- std::thread t1; // t1 is not a thread
- std::thread t2(f1, n + 1); // pass by value
- std::cout << "t2 id = " << t2.get_id()<< std :: endl ;
- std::thread t3(f2, std::ref(n)); // pass by reference
- std::cout << "t3 id = " << t3.get_id()<< std :: endl ; //t3.join();
- std::thread t4(std::move(t3)); // t4 is now running f2(). t3 is no longer a thread
- std::cout << "t4 id = " << t4.get_id()<< std :: endl ;
- std::thread t5(&foo::bar, &f,1); // t5 runs foo::bar() on object f
- std::thread t7(&foo::bar2, &f); // t5 runs foo::bar() on object f
- std::thread t6(b); // t6 runs baz::operator() on object b
- t2.join();
- t4.join();
- t5.join();
- t7.join();
- t6.join();
- std::cout << "Final value of n is " << n << '\n';
- std::cout << "Final value of foo::n is " << f.n << '\n';
- }
指向当前线程std::this_thread
例如std::this_thread::get_id()
get_id | 获取线程 ID |
joinable | 检查线程是否可被 join |
join | Join 线程 |
detach | Detach 线程 |
swap | Swap 线程 |
native_handle | 返回 native handle |
hardware_concurrency [static] | 检测硬件并发特性 |
detch
称为分离线程函数,使用detach()函数会让线程在后台运行,即说明主线程不会等待子线程运行结束才结束
- #include <iostream>
- #include <thread>
- #include <windows.h>
- void func(){
- for (int i = 0; i < 100; ++i) {
- std::cout<<"thread::func"<<std::endl;
- }
- }
- int main() {
- std::thread my_thread(func);
- // Sleep(1);
- my_thread.detach();
- // my_thread.join();
- return 0;
- }
由于使用的是detch函数,新线程与主线程分离,在detch函数执行完成,主线程main函数结束,my_thread对象销毁,还未执行一次打印线程也就结束了,这才造成这样的结果。下面我们加上Sleep(1);这句话,观察结果:
thread::func
thread::func
thread::func
thread::func
。。。。
线程(函数)的传入参数,引用&会失效,指针*还是会传递地址。
(在detach情况下发生,join下不会发生)
- #include <iostream>
- #include <thread>
- #include <string>
- using namespace std;
-
- void myprint(const int &i, char *pmybuf){
- //i并不是mavar的引用,实际是值传递
- //推荐改为const int i
- cout<<i<<endl;
- //指针在detach子线程时,还是指向原来的地址。但是此时地址已经被主线程释放会报错
- cout<< pmybuf <<endl;
- }
-
- int main(){
-
- int mvar=1;
- int &mvary=mvar;
- char mybuf[]="this is a test";
- thread my_thread(myprint, mvar, mybuf);//第一个参数是函数名,后两个参数是函数的参数
- // my_thread.join();//等待子线程执行结束
- my_thread.detach();
- cout<<"I love China"<<endl;
- return 0;
- }
myprint内容并不会被打印;
- #include <iostream>
- #include <thread>
- #include <string>
- using namespace std;
-
- class A{
- public:
- int m_i;
- A(int a):m_i(a){cout<<"gouzao fun run"<<endl;}
- A(const A &a):m_i(a.m_i){cout<<"copy gouzao fun run"<<endl;}
- ~A(){cout<<"xigou fun run"<<endl;}
- };
-
- void myprint(const int i, const A &pmybuf){
-
- cout<< &pmybuf <<endl;
- }
-
- int main(){
-
- int mvar=1;
- int mysec=12;
- // 如果是隐式转换,转换过程在子线程中执行,会有可能主线程执行完还没进行转换
- // 因此需要显式的转换,构造临时对象
- // 在线程声明时立刻执行构造
- // thread my_thread(myprint, mvar, mysec);//第一个参数是函数名,后两个参数是函数的参数
- thread my_thread(myprint, mvar, A(mysec));//第一个参数是函数名,后两个参数是函数的参数
-
- // my_thread.join();//等待子线程执行结束
- my_thread.detach();
- cout<<"I love China"<<endl;
-
- return 0;
- }
- gouzao fun run
- copy gouzao fun run
- copy gouzao fun run
- xigou fun run
- xigou fun run
- I love China
- 0xfd6f58
- xigou fun run
-
- 地址不一定能打印出来
-
- 两次拷贝构造函数:1、转换 2、值传递
1、线程(函数)的传入参数,引用&会失效,指针*还是会传递地址。因为主线程如果销毁了变量内存,子线程的运行就会出错,因此尽量不要在detach()的线程中用传递主线程中的指针
2、为了防止主线程先结束,detach()的线程还没构造,调用构造的时候要显示的调用类的拷贝构造,即为了防止主线程先结束,只有复制一份内存才行
3、想要传递真正的引用需要使用std::ref(param_nanm)
join()没有这个问题。
- #include <iostream>
- #include <thread>
- #include <windows.h>
- void func(int *i,int j)
- {
- *i = *i+1;
- j = j+1;
- std::cout << "I in ="<< *i << std::endl;
- std::cout << "J in ="<< j << std::endl;
-
- }
- int main()
- {
- int i = 0;
- int j = 0;
- std::thread my_thread(func, &i,j);
-
- my_thread.join();
- std::cout << "I out ="<< i << std::endl;
- std::cout << "J out ="<< j << std::endl;
-
- system("pause");
- return 0;
- }
I in =1
J in =1
I out =1
J out =0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。