临界区 临界资源 线程同步是啥?windows上的内核对象是什么?老师说是句柄。线程死锁。
一.线程的状态
线程在操作系统中一般有以下几种状态:
- 就绪态(Ready):线程已经创建好,并且等待被调度执行,但是还未开始执行。
- 运行态(Running):线程正在被调度执行,执行线程的代码。
- 阻塞态(Blocked):线程在等待某些事件发生的时候,在这个期间内其他线程可能在运行。此时,被阻塞的线程不占用 CPU 时间。
- 暂停态(Suspended):线程被挂起或者中止或者线程函数结束但是没有销毁,此时线程处于暂停态。
二.线程的终止方式
a.使用线程终止函数TerminateThread(不推荐):
Windows提供了一个线程终止函数TerminateThread,但是这个函数有如下缺点,而且这些缺点很多都是让人无法忍受的:
- 被终止的线程没有机会清理自己,也不会抛出异常,这可能造成死锁 和 程序崩溃;
- 目标线程的堆栈无法被释放,如果程序没有退出的话,那么这个线程可能会造成内存泄漏;
- 目标线程如果动态加载了动态库,那么这些动态库也无法被卸载掉,这将造成内存泄漏;
- 如果线程在锁住了critical section的时候被终结,那么这个critical section永远无法被释放,那么其他试图获得critical seciton的线程将永远等待下去,这可能造成死锁 和 程序崩溃。
小结:可以看到上述四点,任何一点都会影响程序的稳定性,要么内存泄漏!要么程序死锁!要么程序崩溃!
b.使用简单的标记判断,然线程清理自己并退出(推荐):
通过在线程中设置判断标记,当达到某个条件时线程进入退出流程。而其标记值的控制则由其他线程来控制。
三.什么是内核对象?
Windows中有很多像进程对象、线程对象、文件对象等等这样的对象,我们称之为Windows内核对象。内核对象是系统地址空间中的一个内存块,由系统创建并维护,这个内存对象是一个数据结构,维护着与对象相关的信息(如计数器)。内核对象为内核所拥有,而不为进程所拥有,所以不同进程可以访问同一个内核对象。
内核对象何时销毁
操作系统内核通过计数器知道有多少进程在使用这个内核对象.(因为进程终止后,内核对象不一定销毁,只有当计数器归0 时,操作系统内核才会销毁内核对象)
四.线程的同步方式
在 C++ 中,常见的线程同步方式包括:
1. 互斥锁(Mutex Lock):这是一种基本的线程同步方式,保证多个线程访问共享资源时只有一个线程拥有该资源。例如,当多个线程都需要读写某个全局变量时,可以使用互斥锁来保证同一时刻只有一个线程访问该变量。
2. 读写锁(Reader-Writer Lock):与互斥锁类似,但是读写锁可以允许多个线程同时读取共享资源,但只允许一个线程写入共享资源。例如,当多个线程都需要读取某个数据结构时,可以使用读写锁提高并发度。
3. 条件变量(Condition Variable):条件变量可以让线程等待某个条件达成时再继续执行,这种方式常常用于生产者-消费者模型中。例如,当生产者生产数据过快,导致队列已满时,可以让生产者线程等待条件变量,直到队列不满时再继续生产。
4. 信号量(Semaphore):信号量可用于限制并发访问某些共享资源的数量。例如,当多个线程需要访问有限的数据库连接时,可以使用信号量保证最多只有固定数量的线程可以同时访问该连接。
5. 原子操作(Atomic Operation):原子操作可以确保操作的不可分割性,从而避免线程之间的竞争。例如,当多个线程都需要更新某个计数器时,可以使用原子操作保证每次操作的正确性。