几个知识点:
1.线程需要在下面两种情况下互相进行通信:
- 当有多个线程访问共享资源而不使资源被破坏时;
- 当一个线程需要将某个任务已经完成的情况通知另外一个或多个线程时。
2.线程同步问题在很大程度上与原子访问有关,所谓原子访问,是指线程在访问资源时能够确保所有其他线程都不在同一时间访问相同的资源。
3.使用互锁函数可以保证以原子操作方式进行:InterlockedExchangeAdd(传递负值表示减)、InterlockedExchange、InterlockedExchangePointer、InterlockedCompareExchange、InterlockedCompareExchangePointer。
4.使用__declspec(align(32))来调整结构中的字节对齐。
5.对于需要不断查询的共享变量,应该使用volatile关键字,它告诉编译器,变量可以被应用程序本身以外的某个东西进行修改,这些东西包括操作系统、硬件或同时执行的线程等。因而,volatile会告诉编译器,不要对该变量进行任何优化,并且总是重新加载来自该变量的内存单元的值。
6.关键代码段是指一个小代码段,在代码能够执行前,它必须独占对某些共享资源的访问权。EnterCriticalSection和LeaveCriticalSection以及CRITICAL_SECTION结构可以用于完成这项工作。CRITICAL_SECTION结构需要初始化(InitializeCriticalSection),并在进程的线程不再需要访问共享资源时清除(DeleteCriticalSection)。
7.为了提高关键代码段的运行性能,Microsoft将循环锁纳入了这些代码段。当EnterCriticalSection函数被调用时,它就使用循环所进行循环,以便设法多次获取资源。只有当取得该资源的每次试图都失败时,该线程才转入内核方式,一边进入等待状态。通过InitializeCriticalSectionAndSpinCount可以初始化循环锁迭代次数。使用SetCriticalSectionSpinCount可以改变关键代码段的循环次数。
8.使用关键代码段时的一些提示和技巧:
- 每个共享资源使用一个CRITICAL_SECTION变量;
- 同时访问多个资源时,确保按照完全相同的顺序请求对资源的访问;
- 不要长时间运行关键代码段。