凡科企业网站如何建设,什么是ip地址和域名,wp怎么打开wordpress,优化大师软件大全thread是C11版本中出现的线程对象#xff0c;可以让程序员非常方便地创建线程。 非空的thread对象创建以后#xff0c;线程就会自动运行起来。简单地理解#xff0c;一个线程对象中会传入一个函数指针#xff0c;之后编译器会构造一个栈#xff0c;将这个函数指针压栈。函…thread是C11版本中出现的线程对象可以让程序员非常方便地创建线程。 非空的thread对象创建以后线程就会自动运行起来。简单地理解一个线程对象中会传入一个函数指针之后编译器会构造一个栈将这个函数指针压栈。函数就可以视为任务从而实现了任务并发。
一、如何创建线程对象
1空thread对象
thread t;如果后面没有对其赋值的话这就是一个毫无意义的操作。
2使用全局函数创建thread对象
void f(){coutI love codingendl;
}
int main()
{thread t(f);t.join();
}全局函数也可以带参数
void f(int a){coutI love codingendl;couta;
}
int main()
{thread t(f,1);t.join();
}3使用静态成员函数创建thread对象
class A{
public:static void f();
};void A::f(){coutI love codingendl;
}
int main()
{thread t(A::f);t.join();
}因为静态函数是类公有的所以只需要标注类名即可。
4使用非静态成员函数创建thread对象
class A{
public:void f();
};void A::f(){coutI love codingendl;
}
int main()
{A a;thread t(A::f,a);t.join();
}首先需要将对象构造出来然后将对象的this指针作为入参。
二、线程持有的资源
网上有各种各样的多线程教程老生常谈的一句话是“线程持有的资源如何如何”。那么thread到底持有的是什么资源 本人才疏学浅操作系统学的实在是不咋地深入理解不太行。但是这个资源可以简单看作一个结构体
_Thrd_t _Thr; //其实_Thrd_t 是类型的别名typedef _Thrd_imp_t _Thrd_t; // 而_Thrd_imp_t是一个结构体typedef struct { /* 线程 标识符 */void *_Hnd; /* 操作系统句柄 */unsigned int _Id; // 线程id
} _Thrd_imp_t;thread持有的资源可以看作是一个线程id一个操作系统句柄。后面会说明这两个资源每个thread对象都是不一样的。
所以thread对象只能移动构造不能拷贝构造。只能移动赋值不能拷贝赋值。
void f(){
}
int main()
{thread t1(f);coutt1 id : t1.get_id()endlendl;thread t2(move(t1));coutt1 id : t1.get_id()endl;coutt2 id : t2.get_id()endl;t2.join();
}输出
t1 id : 2t1 id : thread::id of a non-executing thread
t2 id : 2可见移动构造之后t1持有的资源全部给了t2. 假如有一种场景f()正在执行发生了资源移动有问题吗 没有任何问题。因为线程实际上是操作系统持有的资源当thread对象创建好以后线程怎么跑起来和thread对象基本没关系了thread对象里面不过是保存了一个句柄句柄就是指向操作系统内核的指针。资源移动无非是将指针转移给了其他的thread对象。
但是thread保留了这个句柄说明对象就有了这个线程的所有权可以阻塞它、分离它或者进行其他操作。