品牌网站设计打造,适应移动端网站模板,wordpress添加微信分享功能,沈阳网络营销推广的公司创建线程以及相关函数
当用thread类创建线程对象绑定函数后#xff0c;该线程在主线程执行时就已经自动开始执行了,join起到阻塞主线程的作用
#include iostream
#include thread
#include string
using namespace std;
//测试函数
void printStrin…创建线程以及相关函数
当用thread类创建线程对象绑定函数后该线程在主线程执行时就已经自动开始执行了,join起到阻塞主线程的作用
#include iostream
#include thread
#include string
using namespace std;
//测试函数
void printString(string str)
{cout str endl;
}
int main()
{//创建线程需要包括thread头文件,构造函数后续参数里可选放入线程绑定函数的参数thread thread1(printString,Hello World!);//joinable函数,有些线程不一定能用join或者detach,joinable返回一个布尔值true时使用join增加严谨性bool flag thread1.joinable();if (flag)thread1.join();//主程序等待线程执行完毕,不加join可能会导致线程绑定的函数没执行完主程序就结束了//分离主线程和子线程会可能导致子线程还未执行完毕主线程就结束了/*thread1.detach();*/return 0;
}使用detach输出结果一般使用较少 更直观的join和joinable的例子
#include iostream
#include thread
using namespace std;void display()
{for (int i 0; i 100; i)cout i ;cout endl 子线程结束 endl;
}int main()
{thread thread1(display);bool flag thread1.joinable();if (flag)thread1.join();cout 主线程结束 endl;return 0;
}输出 不难发现主线程阻塞在了join中等待子线程执行完毕再往下执行
常见问题以及解决方法
一般注意变量的声明周期即可
绑定函数的参数为引用
使用ref()函数
#include iostream
#include thread
using namespace std;void test01(int a)
{a 1;
}
int main()
{int a 11;//绑定函数时参数,传递引用时需要用std下的ref函数将变量转换为引用类型否则thread无法判断为引用类型thread thread1(test01, ref(a));if (thread1.joinable())thread1.join();cout a endl;return 0;
}错误例子运行结果报错也有可能不报错 错误原因在本例中a不在main中函数执行完后内存会释放掉由于是线程模式test01和test02的执行速度不一致有可能在test02执行完后test01还没有执行完所以导致了空指针异常 解决方法将a变成局部变量
#include iostream
#include thread
using namespace std;
thread thread1;
void test01(int a)
{a 1;
}void test02()
{int a 11;//绑定函数时参数,传递引用时需要用std下的ref函数将变量转换为引用类型否则thread无法判断为引用类型thread1 thread(test01, ref(a));
}
int main()
{test02();if (thread1.joinable())thread1.join();return 0;
}指针提前释放
//指针案例
void test03(int* a)
{cout *a * a endl;
}
int main()
{int* p new int(1);thread thread1(test03,p);//在join之前手动释放了指针指针指向的空间值变成了随机值delete p;if (thread1.joinable())thread1.join();return 0;
}类成员函数作为线程函数但对象被提前释放
其实跟指针的报错差不多注意在join()之前不要释放对象即可 智能指针可以减少在join()之前手动释放的问题它会自动调用析构函数自己销毁对象 整体源代码
#include iostream
#include thread
#include memory
using namespace std;
//引用案例
void test01(int a)
{a 1;
}
//指针案例
void test03(int* a)
{cout *a * a endl;
}
//类案例
class A {
public:void func(){cout 类成员函数作为线程函数 endl;}
};
int main()
{A a;//类成员函数作为线程函数时需要用来制定成员函数的地址,同时还需要传递指针/引用thread thread1(A::func,a);thread1.join();//智能指针,已经是指针了shared_ptrA b make_sharedA();//直接传入值即可thread thread2(A::func, b);thread2.join();return 0;
}互斥锁解决变量访问互质问题
学过OS这部分就很容易理解了 只是C具体实现罢了具体看代码 线程安全如果多线程程序每一次运行的结果跟单线程程序运行的结果是一样的那么就称这个线程是安全的
#include iostream
#include thread
#includemutex
using namespace std;
mutex mtx;
int a 0;
void add()
{for (int i 0; i 1000; i){//上锁相当于P(mutex)mtx.lock();a;//解锁相当于V(mutex)mtx.unlock();}}
int main()
{//创建两个线程thread thread1(add);thread thread2(add);thread1.join();thread2.join();//输出共享变量cout a endl;return 0;
}