自学C++ day12 thread 库

# if 0
#include <iostream> 
#include <thread> 


using namespace std;


// 线程库
/*
	在C++11之前,涉及到多线程问题,都是和平台相关的
*/

/*
*		thread()         构造一个线程对象,没有关联任何线程函数,即没有启动任何线程	
*		thread(fn,arg1,arg2,...)    构造一个线程对象,并关联线程函数fn,arg1,arg2..为线程函数的参数
*		get_id()			获取线程id
*		jionable()        线程是否还在执行,joinable 代表的是一个正在执行中的线程
*		jion()			  函数在调用后会阻塞住线程,当该线程结束后,主线程继续执行
*		detach()		  在线程创建线程对象后马上调用,用于把被创建线成于线程对象分离,所为线程分离
* 
*/

// 注意:
//	1.线程是操作系统中的一个概念,线程对象可以关联一个线程,用来控制线程以及获取线程的状态
//	2.当创建线程对象后,没有提供线程函数,该对象实际没有对应任何线程
#if 0
int main() {
	std::thread t1;
	std::cout << t1.get_id() << std::endl;
	return 0;
}
#endif 
// get_id() 返回值为id类型,id类型实际为std::thread 命名空间下封装的一个类,该类中包含一个结构体
#if 0
typedef struct {
	void* _Hnd;
	unsigned int _Id;
} _Thrd_imp_t;
#endif 

// 3. 当创建一个线程后,并给线程关联线程函数,该线程就被启动,与主线程一起运行。
// 线程函数可以由以下三种方式提供
// (1) 函数指针
// (2) lambda 表达式
// (3) 函数对象(仿函数) 

// 4. thread类是防拷贝的,不允许拷贝以及赋值,但是可以移动构造和移动赋值,及将一个线程对象关联线程的状态转移给其他线程对象,转移期间不影响线程执行

// 5. 可以通过 jionable() 函数判断线程是否是有效的,如果是以下任意情况,则线程无效
//	(1)采用无参构造函数构造的线程对象
//	 (2) 线程对象的状态已经转移给其他线程对象
//   (3) 线程已近调用join 或者 detach 结束




// 线程函数参数
// 线程函数的参数是以值拷贝的方式拷贝到线程栈空间中的。 因此: 即使线程参数为引用参数,在线程中修改后也不能修改外部实参
// 因为其实际引用的是线程栈中的拷贝,而不是外部实参。


#if 0
void ThreadFun1(int& x){
	x += 10;
}

void ThreadFun2(int* x) {
	*x += 10;
}

int main() {
	int a = 10;
	// 在线程函数中对 a进行修改,不会影响外部实参,因为:线程参数虽然是引用方式,但其实际引用的是线程中的拷贝
	thread t1(ThreadFun1, a);
	t1.join();
	cout << a << endl;

	// 如果想要通过形参改变外部实参时,必须借助 std::ref()函数
	thread t2(ThreadFun1, ref(a));
	t2.join();
	cout << a << endl;

	// 地址拷贝
	thread t3(ThreadFun2, &a);
	t3.join();
	cout << a << endl;
	return 0;

}
#endif 
// 如果类成员函数作为线程参数时,必须将this作为线程函数参数!



// join 与 detach 
// 启动一个线程后,当这个线程结束的时候,如何去回收线程所使用的资源呢?
// join()  == pthread_wait() : 主线程被阻塞,当新线程终止时,join() 会自动清理相关的线程资源然后返回
// 主线程继续向下执行让后销毁线程对象。 由于join() 清理了线程的相关资源,thread 对象与已销毁的线程就没有关系了
// 因此一个线程对象只能调用一次join() 否则程序崩溃!
// 注意线程回收问题!


// detach() == pthread_detach() 线程分离,线程结束后也不会通知主线程。线程结束后资源能正确回收。



// 原子操作 && 锁
#if 0
int main() {
	cout << "sb" << endl;
	return 0;
}
#endif 

// 原子性操作库!
// #include <mutex> 
// #include <atomic> 原子类库!

#include <atomic>
// 可以使用atomic 模板,定义出需要的任意原子类型!
atomic<string> t;

// 锁 C++11 中,采用RALL的方式对锁进行了封装,及lock_guard 和 unique_lock。

// mutex 是不可重入锁.
// lock() :上锁,锁住互斥量 阻塞上锁!
// unlock() : 解锁,释放互斥量的所有权!
// try_lock() :尝试锁住互斥量,如果互斥量被其他线程所占有,则当前线程不会被阻塞。 如果上锁成功 return true else return false; 


// recursive_mutex : 可重入锁.

// timed_mutex : 定时阻塞锁。
	// try_lock_for() 接受一个时间范围,表示在这一段时间范围之内线程如果没有获得锁则被阻塞住。
	// try_lock_until() 接受一个时间点作为参数,在指定时间未来到前,如果没有获得锁则会被阻塞住,如果此期间其他线程释放了锁,
	// 则该线程可以获得对互斥量的锁,如果超时返回false;

// recursive_timed_mutex : 定时可重入阻塞锁。

#endif 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值