企业网站备案管理系统,深圳福田区临时管控区,宠物出售的网站怎么做,宿迁房价2023年最新房价thread类
在C11之前#xff0c;涉及到多线程问题#xff0c;都是和平台相关的#xff0c;比如windows和linux下各有自己的接口#xff0c;这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行支持了#xff0c;使得C在并行编程时不需要依赖第三方库#xff0c…thread类
在C11之前涉及到多线程问题都是和平台相关的比如windows和linux下各有自己的接口这使得代码的可移植性比较差。C11中最重要的特性就是对线程进行支持了使得C在并行编程时不需要依赖第三方库而且在原子操作中还引入了原子类的概念。要使用标准库中的线程必须包含 thread 头文件
构造 我们可以看到thread类不支持拷贝构造delete关键词表示声明了某函数但禁止被使用在编译时会直接报错但支持传右值引用和完美转发。第一个参数是线程创建调用的函数第二个是可变参数列表支持传递多个参数。 举个例子
#includethread
#includeiostreamusing namespace std;
void Func(int n,int num)
{for (int i 0; i n; i){cout num:i endl;}cout endl;
}int main()
{//thread t1(Func, 10,1);cinn;thread t1([n](int num){for(int i0;in;i){coutnum:iendl;},n);thread t2(Func, 20,2);t1.join();t2.join();return 0;
}当然这里func也可以换成lambda表达式其次thread类虽然不支持拷贝构造但支持移动构造和赋值。
namespace this_thread yield implementation:实施实行 当一个线程调用此函数将它的时间片交还给操作系统让操作系统reschedule调度从而避免阻塞等待。
mutex类
问题引入
看下面这段代码
int x 0;
void func(int n)
{for (int i 0; i n; i)x 1;
}int main()
{thread t1(func, 10000);thread t2(func, 20000);t1.join();t2.join();cout x endl;return 0;
}按理来说执行结果应该是30000但实际上执行结果不但不为30000而且每次还不一样。
解决方案 定义一个全局的锁在每一次对全局变量x的时候互斥访问临界资源
成员函数 lockguard
templateclass Lock
class LockGuard
{
public:LockGuard(Lock lk):_lk(lk){_lk.lock();}~LockGuard(){_lk.unlock();}private:Lock _lk //成员变量可以是引用但必须在初始化列表初始化
};但程序抛异常时可能来不及释放锁就被catch了进而会造成死锁状态用RAII的方式lock_guard会在作用域结束时由编译器自动调用析构函数
条件变量
实现两个线程交替打印1到100的数
//两个线程交替分别打印奇数和偶数
int main()
{mutex mtx;condition_variable cond;int n 100;int x 1;thread t1([, n]() {while (x n){unique_lockmutex lock(mtx);if (x % 2 0)//打印奇数偶数阻塞cond.wait(lock);cout this_thread::get_id() :xendl;cond.notify_one();}});thread t2([, n]() {while (x n){unique_lockmutex lock(mtx);if (x % 2 ! 0)cond.wait(lock);cout this_thread::get_id() :x endl;cond.notify_one();}});t1.join();t2.join();return 0;
}如果不加奇偶判断那么假设t1打完数字1后通知t2此时t1与t2是竞争cpu出了作用域lock自动释放如果不阻塞t1那么t1很有可能再次获取到锁所以存在t1连续运行的情况