几个WindowAPI

1 Create Mutex

作用:

  找出当前系统是否已经存在指定进程的实例。如果没有则创建一个互斥体。CreateMutex()函数可用来创建一个有名或无名的互斥量对象,其函数原型为:

VC声明:

HANDLE CreateMutex(

  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针

  BOOL bInitialOwner, // 初始化互斥对象的所有者

  LPCTSTR lpName // 指向互斥对象名的指针

  );

说明:

  创建一个互斥体(MUTEX)

  返回值

  Long,如执行成功,就返回互斥体对象的句柄;零表示出错。会设置GetLastError。即使返回的是一个有效句柄,但倘若指定的名字已经存在,GetLastError也会设为ERROR_ALREADY_EXISTS

  lpMutexAttributes SECURITY_ATTRIBUTES,指定一个SECURITY_ATTRIBUTES结构,或传递零值(将参数声明为ByVal As Long,并传递零值),表示使用不允许继承的默认描述符

  bInitialOwner Long,如创建进程希望立即拥有互斥体,则设为TRUE。一个互斥体同时只能由一个线程拥有

  lpName String,指定互斥体对象的名字。用vbNullString创建一个未命名的互斥体对象。如已经存在拥有这个名字的一个事件,则打开现有的已命名互斥体。这个名字可能不与现有的事件、信号机、可等待计时器或文件映射相符

注意:

  一旦不再需要,注意必须用CloseHandle函数将互斥体句柄关闭。从属于它的所有句柄都被关闭后,就会删除对象

  进程中止前,一定要释放互斥体,如不慎未采取这个措施,就会将这个互斥体标记为废弃,并自动释放所有权。共享这个互斥体的其他应用程序也许仍然能够用它,但会接收到一个废弃状态信息,指出上一个所有进程未能正常关闭。这种状况是否会造成影响取决于涉及到的具体应用程序

示例:

  HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");// 检查错误代码

  if (GetLastError() == ERROR_ALREADY_EXISTS)

  {

  // 如果已有互斥量存在则释放句柄并复位互斥量

  CloseHandle(m_hMutex);

  m_hMutex = NULL;

  // 程序退出

  return FALSE;

  };

  //上面这段代码演示了有名互斥量在进程互斥中的用法。代码的核心是CreateMutex()对有名互斥量的创建。

  CreateMutex() 用于有独占要求的程序 (在其进程运行期间不允许其他使用此端口设备的程序运行,或不允许同名程序运行)。

2 WSAStartup

  WSAStarup,是Windows SocKNDs Asynchronous的启动命令、Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令。

说明:

  WSAStarup,即WSA(Windows SocKNDs Asynchronous,Windows套接字异步)的启动命令。是Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令(Ps:Winsock 是由Unix下的BSD Socket发展而来,是一个与网络协议无关的编程接口)。

  为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,因此需要调用WSAStartup函数。使用Socket的程序在使用Socket之前必须调用WSAStartup函数。该函数的第一个参数指明程序请求使用的Socket版本,其中高位字节指明副版本、低位字节指明主版本;操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了。

函数原型:

#include

  int PASCAL FAR WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );wVersionRequested

  Windows Sockets API提供的调用方可使用的最高版本号。高位字节指出副版本(修正)号,低位字节指明主版本号。lpWSAData 指向WSADATA数据结构的指针,用来接收Windows Sockets实现的细节。

3 WaitForSingleObject

原型:

DWORD WINAPI WaitForSingleObject(

  __in HANDLE hHandle,

  __in DWORD dwMilliseconds

  );

参数:

  hHandle [in]对象句柄。可以指定一系列的对象,如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。

  当等待仍在挂起状态时,句柄被关闭,那么函数行为是未定义的。该句柄必须具有 SYNCHRONIZE 访问权限。

  dwMilliseconds [in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle 标记的对象被触发,或者时间到了。如果dwMilliseconds 为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds 为INFINITE,对象被触发信号后,函数才会返回。

返回值:

  执行成功,返回值指示出引发函数返回的事件。它可能为以下值:

WAIT_ABANDONED0x00000080L The specified object is a mutex object that was not released by the thread that owned the mutex object before the owning thread terminated. Ownership of the mutex object is granted to the calling thread and the mutex state is set to nonsignaled. 
If the mutex was protecting persistent state information, you should check it for consistency.
WAIT_OBJECT_00x00000000L The state of the specified object is signaled.
WAIT_TIMEOUT0x00000102L The time-out interval elapsed, and the object's state is nonsignaled.
WAIT_FAILED(DWORD)0xFFFFFFFF The function has failed. To get extended error information, call GetLastError.

  WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,直到hHandle所指向的对象变为有信号状态时为止。

示例:

  先创建一个全局Event对象g_event:
  CEvent g_event;

  在程序中可以通过调用CEvent::SetEvent设置事件为有信号状态。

  下面是一个线程函数MyThreadPro()

  UINT CFlushDlg::MyThreadProc( LPVOID pParam )
  {
    WaitForSingleObject(g_event,INFINITE); 
    {
      For(;;)
      {
        ……
      }
    }
    return 0; 
  }   

  在这个线程函数中只有设置g_event为有信号状态时才执行下面的for循环,因为g_event是全局变量,所以我们可以在别的线程中通过g_event. SetEvent控制这个线程。

  还有一种用法就是我们可以通过WaitForSingleObject函数来间隔的执行一个线程函数的函数体

  UINT CFlushDlg::MyThreadProc( LPVOID pParam )
  {
    while(WaitForSingleObject(g_event,MT_INTERVAL)!=WAIT_OBJECT_0)
    {
      ……
    }
    return 0; 
  } 

  在这个线程函数中可以通过设置MT_INTERVAL来控制这个线程的函数体多久执行一次,当事件为无信号状态时函数体隔MT_INTERVAL执行一次,当设置事件为有信号状态时,线程就执行完毕了。

posted on 2011-09-04 18:49  马马特  阅读(298)  评论(0编辑  收藏  举报

导航