??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美日韩一区二区在线视频,一本色道久久综合一区,国产午夜精品一区理论片http://www.aygfsteel.com/tinysun/category/37797.htmlzh-cnFri, 20 Mar 2009 13:38:49 GMTFri, 20 Mar 2009 13:38:49 GMT60Win32API之进E相?/title><link>http://www.aygfsteel.com/tinysun/archive/2009/03/20/261103.html</link><dc:creator>何克?/dc:creator><author>何克?/author><pubDate>Fri, 20 Mar 2009 10:01:00 GMT</pubDate><guid>http://www.aygfsteel.com/tinysun/archive/2009/03/20/261103.html</guid><wfw:comment>http://www.aygfsteel.com/tinysun/comments/261103.html</wfw:comment><comments>http://www.aygfsteel.com/tinysun/archive/2009/03/20/261103.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/tinysun/comments/commentRss/261103.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/tinysun/services/trackbacks/261103.html</trackback:ping><description><![CDATA[<p align="right"> </p> <p><font size="3"><font color="#000000"><strong>从别人BLOG上看到的东西~~很有用~~C来~Q!</strong></font></font></p> <p><font size="3"><font color="#000000"><strong>CancelWaitableTimer q个函数用于取消一个可以等待下ȝ计时器操?<br /> CallNamedPipe q个函数׃个希望通过道通信的一个客戯E调?<br /> ConnectNamedPipe 指示一台服务器{待下去Q直臛_h同一个命名管道连?<br /> CreateEvent 创徏一个事件对?<br /> CreateMailslot 创徏一个邮路。返回的句柄由邮路服务器使用Q收件hQ?<br /> CreateMutex 创徏一个互斥体QMUTEXQ?<br /> CreateNamedPipe 创徏一个命名管道。返回的句柄q道的服务器端使用 <br /> CreatePipe 创徏一个匿名管?<br /> CreateProcess 创徏一个新q程Q比如执行一个程序) <br /> CreateSemaphore 创徏一个新的信h <br /> CreateWaitableTimer 创徏一个可{待的计时器对象 <br /> DisconnectNamedPipe 断开一个客户与一个命名管道的q接 <br /> DuplicateHandle 在指Z个现有系l对象当前句柄的情况下,为那个对象创Z个新句柄 <br /> ExitProcess 中止一个进E?<br /> FindCloseChangeNotification 关闭一个改动通知对象 <br /> FindExecutable 查找与一个指定文件关联在一L(fng)E序的文件名 <br /> </strong>FindFirstChangeNotification 创徏一个文仉知对象。该对象用于监视文gpȝ发生的变?<br /> FindNextChangeNotification 重设一个文件改变通知对象Qo(h)其l监视下一ơ变?<br /> FreeLibrary 释放指定的动态链接库 <br /> GetCurrentProcess 获取当前q程的一个伪句柄 <br /> GetCurrentProcessId 获取当前q程一个唯一的标识符 <br /> GetCurrentThread 获取当前U程的一个伪句柄 <br /> GetCurrentThreadId 获取当前U程一个唯一的线E标识符 <br /> GetExitCodeProces 获取一个已中断q程的退Z?<br /> GetExitCodeThread 获取一个已中止U程的退Z?<br /> GetHandleInformation 获取与一个系l对象句柄有关的信息 <br /> GetMailslotInfo 获取与一个邮路有关的信息 <br /> GetModuleFileName 获取一个已装蝲模板的完整\径名U?<br /> GetModuleHandle 获取一个应用程序或动态链接库的模块句?<br /> GetPriorityClass 获取特定q程的优先?<br /> GetProcessShutdownParameters 调查pȝ关闭时一个指定的q程相对于其它进E的关闭早迟情况 <br /> GetProcessTimes 获取与一个进E的l过旉有关的信?<br /> GetProcessWorkingSetSize 了解一个应用程序在q行q程中实际向它交付了多大定w的内?<br /> GetSartupInfo 获取一个进E的启动信息 <br /> GetThreadPriority 获取特定U程的优先?<br /> GetTheardTimes 获取与一个线E的l过旉有关的信?<br /> GetWindowThreadProcessId 获取与指定窗口关联在一L(fng)一个进E和U程标识W?<br /> LoadLibrary 载入指定的动态链接库Qƈ它映射到当前进E用的地址I间 <br /> LoadLibraryEx 装蝲指定的动态链接库Qƈ为当前进E把它映到地址I间 <br /> LoadModule 载入一个Windows应用E序Qƈ在指定的环境中运?<br /> MsgWaitForMultipleObjects {侯单个对象或一pd对象发出信号。如q回条g已经满Q则立即q回 <br /> SetPriorityClass 讄一个进E的优先U别 <br /> SetProcessShutdownParameters 在系l关闭期_(d)为指定进E设|他相对于其它程序的关闭序 <br /> SetProcessWorkingSetSize 讄操作pȝ实际划分l进E用的内存定w <br /> SetThreadPriority 讑֮U程的优先?<br /> ShellExecute 查找与指定文件关联在一L(fng)E序的文件名 <br /> TerminateProcess l束一个进E?<br /> WinExec q行指定的程?<br /> </p> </font></font> <img src ="http://www.aygfsteel.com/tinysun/aggbug/261103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/tinysun/" target="_blank">何克?/a> 2009-03-20 18:01 <a href="http://www.aygfsteel.com/tinysun/archive/2009/03/20/261103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>深入出Win32多线E程序设计之U程通信(?http://www.aygfsteel.com/tinysun/archive/2008/11/30/243521.html何克?/dc:creator>何克?/author>Sun, 30 Nov 2008 05:25:00 GMThttp://www.aygfsteel.com/tinysun/archive/2008/11/30/243521.htmlhttp://www.aygfsteel.com/tinysun/comments/243521.htmlhttp://www.aygfsteel.com/tinysun/archive/2008/11/30/243521.html#Feedback0http://www.aygfsteel.com/tinysun/comments/commentRss/243521.htmlhttp://www.aygfsteel.com/tinysun/services/trackbacks/243521.html?br />
  U程之间通信的两个基本问题是互斥和同步?br />
  U程同步是指U程之间所h的一U制U关p,一个线E的执行依赖另一个线E的消息Q当它没有得到另一个线E的消息时应{待Q直到消息到达时才被唤醒?br />
  U程互斥是指对于׃n的操作系l资源(指的是广义的"资源"Q而不是Windows?res文gQ譬如全局变量是一U共享资源)Q在各线E访问时的排它性。当有若q个U程都要使用某一׃n资源ӞM时刻最多只允许一个线E去使用Q其它要使用该资源的U程必须{待Q直到占用资源者释放该资源?br />
  U程互斥是一U特D的U程同步?br />
  实际上,互斥和同步对应着U程间通信发生的两U情况:(x)

  Q?Q当有多个线E访问共享资源而不使资源被破坏Ӟ

  Q?Q当一个线E需要将某个d已经完成的情况通知另外一个或多个U程时?br />
  在WIN32中,同步机制主要有以下几U:(x)

  Q?Q事?Event);

  Q?Q信号量(semaphore);

  Q?Q互斥量(mutex);

  Q?Q(f)界区(Critical section)?br />
  全局变量

  因ؓ(f)q程中的所有线E均可以讉K所有的全局变量Q因而全局变量成ؓ(f)Win32多线E通信的最单方式。例如:(x)

int var; //全局变量
UINT ThreadFunction(LPVOIDpParam)
{
 var = 0;
 while (var < MaxValue)
 {
  //U程处理
  ::InterlockedIncrement(long*) &var);
 }
 return 0;
}
L(fng)下列E序Q?br /> int globalFlag = false;
DWORD WINAPI ThreadFunc(LPVOID n)
{
 Sleep(2000);
 globalFlag = true;

 return 0;
}

int main()
{
 HANDLE hThrd;
 DWORD threadId;

 hThrd = CreateThread(NULL, 0, ThreadFunc, NULL, 0, &threadId);
 if (hThrd)
 {
  printf("Thread launched\n");
  CloseHandle(hThrd);
 }

 while (!globalFlag)
 ;
 printf("exit\n");
}

  上述E序中用全局变量和while循环查询q行U程间同步,实际上,q是一U应该避免的Ҏ(gu)Q因为:(x)

  Q?Q当ȝE必M自己与ThreadFunc函数的完成运行实现同步时Q它q没有自己q入睡眠状态。由于主U程没有q入睡眠状态,因此操作pȝl箋为它调度C P U旉Q这p占用其他U程的宝贉|间周期;

  Q?Q当ȝE的优先U高于执行ThreadFunc函数的线E时Q就?x)发生globalFlag永远不能被赋gؓ(f)true的情c(din)因为在q种情况下,pȝ决不?x)将M旉片分配给ThreadFuncU程?br />
  事g

  事g(Event)是WIN32提供的最灉|的线E间同步方式Q事件可以处于激发状?signaled or true)或未Ȁ发状?unsignal or false)。根据状态变q方式的不同Q事件可分ؓ(f)两类Q?br />
  Q?Q手动设|:(x)q种对象只可能用E序手动讄Q在需要该事g或者事件发生时Q采用SetEvent?qing)ResetEvent来进行设|?br />
  Q?Q自动恢复:(x)一旦事件发生ƈ被处理后Q自动恢复到没有事g状态,不需要再ơ设|?br />
  创徏事g的函数原型ؓ(f)Q?br />
HANDLE CreateEvent(
 LPSECURITY_ATTRIBUTES lpEventAttributes,
 // SECURITY_ATTRIBUTESl构指针Q可为NULL
 BOOL bManualReset,
 // 手动/自动
 // TRUEQ在WaitForSingleObject后必L动调用ResetEvent清除信号
 // FALSEQ在WaitForSingleObject后,pȝ自动清除事g信号
 BOOL bInitialState, //初始状?br />  LPCTSTR lpName //事g的名U?br /> );

  使用"事g"机制应注意以下事:(x)

  Q?Q如果跨q程讉K事gQ必d事g命名Q在对事件命名的时候,要注意不要与pȝ命名I间中的其它全局命名对象冲突Q?br />
  Q?Q事件是否要自动恢复Q?br />
  Q?Q事件的初始状态设|?br />
  ׃event对象属于内核对象Q故q程B可以调用OpenEvent函数通过对象的名字获得进EA中event对象的句柄,然后这个句柄用于ResetEvent、SetEvent和W(xu)aitForMultipleObjects{函C。此法可以实C个进E的U程控制另一q程中线E的q行Q例如:(x)

HANDLE hEvent=OpenEvent(EVENT_ALL_ACCESS,true,"MyEvent");
ResetEvent(hEvent);

临界?br />
  定义临界区变?br />
CRITICAL_SECTION gCriticalSection;

  通常情况下,CRITICAL_SECTIONl构体应该被定义为全局变量Q以便于q程中的所有线E方便地按照变量名来引用该结构体?br />
  初始化(f)界区

VOID WINAPI InitializeCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向E序员定义的CRITICAL_SECTION变量
);

  该函数用于对pcs所指的CRITICAL_SECTIONl构体进行初始化。该函数只是讄了一些成员变量,它的q行一般不?x)失败,因此它采用了VOIDcd的返回倹{该函数必须在Q何线E调用EnterCriticalSection函数之前被调用,如果一个线E试图进入一个未初始化的CRTICAL_SECTIONQ那么结果将是很N计的?br />
  删除临界?br />
VOID WINAPI DeleteCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个不再需要的CRITICAL_SECTION变量
);

  q入临界?br />
VOID WINAPI EnterCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个你卛_锁定的CRITICAL_SECTION变量
);

  d临界?br />
VOID WINAPI LeaveCriticalSection(
 LPCRITICAL_SECTION lpCriticalSection
 //指向一个你卛_d的CRITICAL_SECTION变量
);

  使用临界区编E的一般方法是Q?br />
void UpdateData()
{
 EnterCriticalSection(&gCriticalSection);
 ...//do something
 LeaveCriticalSection(&gCriticalSection);
}

  关于临界区的使用Q有下列注意点:(x)

  Q?Q每个共享资源用一个CRITICAL_SECTION变量Q?br />
  Q?Q不要长旉q行关键代码D,当一个关键代码段长时间运行时Q其他线E就?x)进入等待状态,q会(x)降低应用E序的运行性能Q?br />
  Q?Q如果需要同时访问多个资源,则可能连l调用EnterCriticalSectionQ?br />
  Q?QCritical Section不是OS核心对象Q如果进入(f)界区的线E??了,无法释放(f)界资源。这个缺点在Mutex中得C弥补?br />
  互斥

  互斥量的作用是保证每ơ只能有一个线E获得互斥量而得以l执行,使用CreateMutex函数创徏Q?

HANDLE CreateMutex(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
 // 安全属性结构指针,可ؓ(f)NULL
 BOOL bInitialOwner,
 //是否占有该互斥量QTRUEQ占有,FALSEQ不占有
 LPCTSTR lpName
 //信号量的名称
);

  Mutex是核心对象,可以跨进E访问,下面的代码给Z从另一q程讉K命名Mutex的例子:(x)

HANDLE hMutex;
hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, L"mutexName");
if (hMutex){
 …
?br /> else{
 …
}

  相关APIQ?br />
BOOL WINAPI ReleaseMutex(
 HANDLE hMutex
);

  使用互斥~程的一般方法是Q?br />
void UpdateResource()
{
 WaitForSingleObject(hMutex,…);
 ...//do something
 ReleaseMutex(hMutex);
}

  互斥(mutex)内核对象能够保U程拥有对单个资源的互斥讉K权。互斥对象的行ؓ(f)Ҏ(gu)与临界区相同,但是互斥对象属于内核对象Q而(f)界区则属于用h式对象,因此q导致mutex与Critical Section的如下不同:(x)

  Q?Q?互斥对象的运行速度比关键代码段要慢Q?br />
  Q?Q?不同q程中的多个U程能够讉K单个互斥对象Q?br />
  Q?Q?U程在等待访问资源时可以讑֮一个超时倹{?br />
  下图更详l地列出了互斥与临界区的不同Q?br />

信号?br />
  信号量是l护0到指定最大g间的同步对象。信号量状态在其计数大?时是有信L(fng)Q而其计数?时是无信L(fng)。信号量对象在控制上可以支持有限数量׃n资源的访问?br />
  信号量的特点和用途可用下列几句话定义Q?br />
  Q?Q如果当前资源的数量大于0Q则信号量有效;

  Q?Q如果当前资源数量是0Q则信号量无效;

  Q?Q系l决不允许当前资源的数量|

  Q?Q当前资源数量决不能大于最大资源数量?br />
  创徏信号?br />
HANDLE CreateSemaphore (
 PSECURITY_ATTRIBUTE psa,
 LONG lInitialCount, //开始时可供使用的资源数
 LONG lMaximumCount, //最大资源数
PCTSTR pszName);

  释放信号?br />
  通过调用ReleaseSemaphore函数Q线E就能够对信标的当前资源数量q行递增Q该函数原型为:(x)

BOOL WINAPI ReleaseSemaphore(
 HANDLE hSemaphore,
 LONG lReleaseCount, //信号量的当前资源数增加lReleaseCount
 LPLONG lpPreviousCount
);

  打开信号?br />
  和其他核心对象一P信号量也可以通过名字跨进E访问,打开信号量的API为:(x)

HANDLE OpenSemaphore (
 DWORD fdwAccess,
 BOOL bInherithandle,
 PCTSTR pszName
);

  互锁讉K

  当必M原子操作方式来修改单个值时Q互锁访问函数是相当有用的。所谓原子访问,是指U程在访问资源时能够保所有其他线E都不在同一旉内访问相同的资源?br />
  L(fng)下列代码Q?br />
int globalVar = 0;

DWORD WINAPI ThreadFunc1(LPVOID n)
{
 globalVar++;
 return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID n)
{
 globalVar++;
 return 0;
}

  q行ThreadFunc1和ThreadFunc2U程Q结果是不可预料的,因ؓ(f)globalVar++q不对应着一条机器指令,我们看看globalVar++的反汇编代码Q?br />
00401038 mov eax,[globalVar (0042d3f0)]
0040103D add eax,1
00401040 mov [globalVar (0042d3f0)],eax

  ?mov eax,[globalVar (0042d3f0)]" 指o(h)?add eax,1" 指o(h)以及(qing)"add eax,1" 指o(h)?mov [globalVar (0042d3f0)],eax"指o(h)之间都可能发生线E切换,使得E序的执行后globalVar的结果不能确定。我们可以用InterlockedExchangeAdd函数解决q个问题Q?br />
int globalVar = 0;

DWORD WINAPI ThreadFunc1(LPVOID n)
{
 InterlockedExchangeAdd(&globalVar,1);
 return 0;
}
DWORD WINAPI ThreadFunc2(LPVOID n)
{
 InterlockedExchangeAdd(&globalVar,1);
 return 0;
}

  InterlockedExchangeAdd保证对变量globalVar的访问具?原子?。互锁访问的控制速度非常快,调用一个互锁函数的CPU周期通常于50Q不需要进行用h式与内核方式的切换(该切换通常需要运?000个CPU周期Q?br />
  互锁讉K函数的缺点在于其只能对单一变量q行原子讉KQ如果要讉K的资源比较复杂,仍要使用临界区或互斥?br />
  可等待定时器

  可等待定时器是在某个旉或按规定的间隔时间发q信号通知的内核对象。它们通常用来在某个时间执行某个操作?br />
  创徏可等待定时器

HANDLE CreateWaitableTimer(
 PSECURITY_ATTRISUTES psa,
 BOOL fManualReset,//人工重置或自动重|定时器
PCTSTR pszName);

  讄可等待定时器

  可等待定时器对象在非Ȁzȝ态下被创建,E序员应调用 SetWaitableTimer函数来界定定时器在何时被Ȁz:(x)

BOOL SetWaitableTimer(
 HANDLE hTimer, //要设|的定时?br />  const LARGE_INTEGER *pDueTime, //指明定时器第一ơ激zȝ旉
 LONG lPeriod, //指明此后定时器应该间隔多长时间激zM?br />  PTIMERAPCROUTINE pfnCompletionRoutine,
 PVOID PvArgToCompletionRoutine,
BOOL fResume);

  取消可等待定时器

BOOl Cancel WaitableTimer(
 HANDLE hTimer //要取消的定时?br /> );

  打开可等待定时器

  作ؓ(f)一U内核对象,W(xu)aitableTimer也可以被其他q程以名字打开Q?br />
HANDLE OpenWaitableTimer (
 DWORD fdwAccess,
 BOOL bInherithandle,
 PCTSTR pszName
);

  实例

  下面l出的一个程序可能发生死锁现象:(x)

#include <windows.h>
#include <stdio.h>
CRITICAL_SECTION cs1, cs2;
long WINAPI ThreadFn(long);
main()
{
 long iThreadID;
 InitializeCriticalSection(&cs1);
 InitializeCriticalSection(&cs2);
 CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFn, NULL, 0,&iThreadID));
 while (TRUE)
 {
  EnterCriticalSection(&cs1);
  printf("\nU程1占用临界?");
  EnterCriticalSection(&cs2);
  printf("\nU程1占用临界?");

  printf("\nU程1占用两个临界?);

  LeaveCriticalSection(&cs2);
  LeaveCriticalSection(&cs1);

  printf("\nU程1释放两个临界?);
  Sleep(20);
 };
 return (0);
}

long WINAPI ThreadFn(long lParam)
{
 while (TRUE)
 {
  EnterCriticalSection(&cs2);
  printf("\nU程2占用临界?");
  EnterCriticalSection(&cs1);
  printf("\nU程2占用临界?");

  printf("\nU程2占用两个临界?);

  LeaveCriticalSection(&cs1);
  LeaveCriticalSection(&cs2);

  printf("\nU程2释放两个临界?);
  Sleep(20);
 };
}

  q行q个E序Q在中途一旦发生这L(fng)输出Q?br />
  U程1占用临界?

  U程2占用临界?

  ?br />
  U程2占用临界?

  U程1占用临界?

  ?br />
  U程1占用临界?

  U程2占用临界?

  ?br />
  U程2占用临界?

  U程1占用临界?

  E序??掉了Q再也运行不下去。因L(fng)输出Q意味着两个U程怺{待Ҏ(gu)释放临界区,也即出现了死锁?br />
  如果我们线E?的控制函数改为:(x)

long WINAPI ThreadFn(long lParam)
{
 while (TRUE)
 {
  EnterCriticalSection(&cs1);
  printf("\nU程2占用临界?");
  EnterCriticalSection(&cs2);
  printf("\nU程2占用临界?");

  printf("\nU程2占用两个临界?);

  LeaveCriticalSection(&cs1);
  LeaveCriticalSection(&cs2);

  printf("\nU程2释放两个临界?);
  Sleep(20);
 };
}

  再次q行E序Q死锁被消除Q程序不再挡掉。这是因为我们改变了U程2中获得(f)界区1?的顺序,消除了线E??怺{待资源的可能性?br />
  由此我们得出l论Q在使用U程间的同步机制Ӟ要特别留心死锁的发生?br />

]]>
վ֩ģ壺 | | | ƽɽ| Դ| | ͺ| ˫Ѽɽ| | | | | | | | | Դ| | | | | | ɽ| | | Ϫ| ຣʡ| ̨| ʵ| | ʲ| ̨| | | ʳ| | | | | ٺ| ̩|