• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2019-11-09 22:13 Aet 隐藏边栏 |   抢沙发  6 
文章评分 1 次,平均分 5.0

线程介绍

Thread

  • 是操作系统能够进行运算调度的最小单位。
  • 它被包含在进程中,是进程中的实际运作单位。
  • 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

线程的内容

  • 我们从主线程的入口main函数,不不断进行函数调用,每次调用的时候,会把所有的参数和返回地址压入到栈中

PC(程序计数器)

  • PC指向当前的指令,而这些指令是放在内存中的。也就是说,每个线程都有一串自己的指针,指向自己所在的内存。

TLS(线程本地存储)

  • 每个进程都有自己独立的内存,线程拥有的自己独立的内存就是TLS,用来储存线程独有的数据。

多线程的好处

创建一个新线程花费时间少(结束一个线程花费的时间也少)

两个线程的切换花费时间少

同一进程内的线程共享文件和内存,因此他们之间相互通信无序调用内核

线程间通信的方式

全局变量

通过全局变量进行通信,就需要对该变量添加volatile关键字
volatile:每次从内存中去读这个值,而不是因编译器优化从缓存的地方读取


DWORD:

  • 在windows.h里面
  • #define DWORD unsigned long;
  • Double Word,每个word为2个字节的长度,DWORD就是双字节,也就是4个字节的长度,每个字节是8位,也就是说DWORD是32位。
  • 经常被用来保存地址或存放指针


WINAPI:

  • #define WINAPI _stdcall;
  • 函数调用的时候,函数入栈的方式是从最右边先入栈
  • 然后_stdcall还规定,被调用函数负责自己使用的栈的回收,也就是说调用者函数只负责压入自己栈中,这就是手工请栈。


CreateThread(成功返回新线程的句柄,失败返回NULL)(参数如下):

  • 线程内核对象的安全属性,NULL表示默认值
  • 线程栈空间大小,0表示默认大小,也就是1MB
  • 新线程所执行的线程函数地址(多个线程可以使用同一个函数地址)
  • 传给线程函数的参数
  • 指定额外的标志来控制线程的创建,0表示线程创建之后立即就可以进行调度;CREATE_SUSPENDED表示线程创建后暂停运行,这样它就无法调度,直到调用了ResumeThread();
  • 将返回线程的ID号,NULL表示不需要返回该线程ID


WaitForSingleObject:

  • 指明一个内核对象的句柄
  • 等待时间
    INFINITE:
  • #define INFINITE 0xFFFFFFFF;
  • 表示该数值的最大值

互斥量

互斥量的功能和临界区很相似。
区别是,Mutex所花费的时间比Critical Section多的多,但是Mutex是核心对象,可以跨进程使用。而且等待一个被锁住的Mutex可以设定为TIMEOUT,不会像Critical Section那样无法得知临界区域的情况,而一直死等。
win32函数:

  • CreateMutex()-创建互斥量
  • OpenMutex()-打开互斥量
  • ReleaseMutex()-释放互斥量
    互斥量的拥有权并非是创建它的那个线程,而是最后对此互斥量进行操作并且尚未进行ReleaseMutex()操作的线程。
    如果一个用于Mutex的线程在返回之前没有进行ReleaseMutex(),那么这个Mutex就被舍弃了,但是当其他线程等待这个Mutex时,仍能返回,并得到一个WAIT_ABANDONED_0返回值。
    能够知道一个Mutex被舍弃是Mutex特有的。

信号量

信号量是解决生产者/消费者问题的关键要素。

事件

用事件来同步线程是最具弹性的。
一个事件具有两种状态:激发状态和未激发状态。也称为有信号状态和无信号状态。
事件种类:

  • 手动重置事件
    被设置为激发状态后,会唤醒所有等待的线程,而且一直保持为激发状态。直到程序把它设置为未激发状态。
  • 自动重置事件
    被设置为激发状态后,会唤醒一个等待中的线程,然后自动恢复为未激发状态。
    所以,用自动重置事件来同步两个线程比较理想。

临界区

CRITICAL_SECTION是最快的。其他的内核锁如互斥量事件,每进一次内核,都需要上千个CPU周期。
使用临界区时,最好不要长时间锁住一份资源。这里所说的长时间是相对的,视不同程序来定。
缺点:
CRITICAL_SECTION不是一个核心对象,无法获知进入临界区的线程是生是死,如果进入临界区的线程挂了,没有释放临界资源,系统无法获知,而且没有办法释放该临界资源。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2021-11-21
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享