随笔 - 2146  文章 - 19 评论 - 11846 阅读 - 1267万

function CreateThread(
  lpThreadAttributes: Pointer; {安全设置}
  dwStackSize: DWORD;
  lpStartAddress: TFNThreadStartRoutine; 
  lpParameter: Pointer; 
  dwCreationFlags: DWORD;
  var lpThreadId: DWORD
): THandle; stdcall;


CreateThread 的第一个参数 lpThreadAttributes 是指向 TSecurityAttributes 结构的指针, 一般都是置为 nil, 这表示没有访问限制; 该结构的定义是:

//TSecurityAttributes(又名: SECURITY_ATTRIBUTES、_SECURITY_ATTRIBUTES)
_SECURITY_ATTRIBUTES = record
  nLength: DWORD;                {结构大小}
  lpSecurityDescriptor: Pointer; {默认 nil; 这是另一个结构 TSecurityDescriptor 的指针}
  bInheritHandle: BOOL;          {默认 False, 表示不可继承}
end;

//TSecurityDescriptor(又名: SECURITY_DESCRIPTOR、_SECURITY_DESCRIPTOR)
_SECURITY_DESCRIPTOR = record
  Revision: Byte;
  Sbz1: Byte;
  Control: SECURITY_DESCRIPTOR_CONTROL;
  Owner: PSID;
  Group: PSID;
  Sacl: PACL;
  Dacl: PACL;
end;


够复杂的, 但我们在多线程编程时不需要去设置它们, 大都是使用默认设置(也就是赋值为 nil).

我觉得有必要在此刻了解的是: 建立系统内核对象时一般都有这个属性(TSecurityAttributes);
在接下来多线程的课题中要使用一些内核对象, 不如先盘点一下, 到时碰到这个属性时给个 nil 即可, 不必再费神.

{建立事件}
function CreateEvent(
  lpEventAttributes: PSecurityAttributes; {!}
  bManualReset: BOOL;
  bInitialState: BOOL;
  lpName: PWideChar
): THandle; stdcall;

{建立互斥}
function CreateMutex(
  lpMutexAttributes: PSecurityAttributes; {!}
  bInitialOwner: BOOL;
  lpName: PWideChar
): THandle; stdcall;

{建立信号}
function CreateSemaphore(
  lpSemaphoreAttributes: PSecurityAttributes; {!}
  lInitialCount: Longint;
  lMaximumCount: Longint;
  lpName: PWideChar
): THandle; stdcall;

{建立等待计时器}
function CreateWaitableTimer(
  lpTimerAttributes: PSecurityAttributes; {!}
  bManualReset: BOOL;
  lpTimerName: PWideChar
): THandle; stdcall;


上面的四个系统内核对象(事件、互斥、信号、计时器)都是线程同步的手段, 从这也能看出处理线程同步的复杂性; 不过这还不是全部, Windows Vista 开始又增加了 Condition variables(条件变量)、Slim Reader-Writer Locks(读写锁)等同步手段.

不过最简单、最轻便(速度最快)的同步手段还是 CriticalSection(临界区), 但它不属于系统内核对象, 当然也就没有句柄、没有 TSecurityAttributes 这个安全属性, 这也导致它不能跨进程使用; 不过写多线程时一般不用跨进程啊, 所以 CriticalSection 应该是最常用的同步手段.

下次接上, 开始学习多线程的同步了.

posted on   万一  阅读(12413)  评论(4编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2008-02-12 WinAPI: SetWindowPos - 改变窗口的位置与状态
2008-02-12 WinAPI: MoveWindow - 改变窗口的位置与大小
2008-02-12 WinAPI: IsIconic、IsZoomed - 分别判断窗口是否已最小化、最大化
2008-02-12 WinAPI: GetParent - 判断两个窗口是不是父子关系
2008-02-12 WinAPI: GetParent - 获取指定窗口的父窗口句柄
2008-02-12 WinAPI: GetFocus - 获取当前拥有焦点的窗口的句柄
2008-02-12 WinAPI: GetActiveWindow - 获取当前活动窗口的句柄


点击右上角即可分享
微信分享提示