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 应该是最常用的同步手段.