×

windowssetevent用法

windowssetevent用法(setactivewindow)

admin admin 发表于2023-03-25 19:34:09 浏览54 评论0

抢沙发发表评论

本文目录一览:

关闭中断可以setevent吗?

如果操作成功,则返回非零值,否则为0。

Win32系统编程API,用于线程间通信。

设置事件的状态为有标记,释放任意等待线程。如果事件是手工的,此事件将保持有标记直到调用ResetEvent,这种情况下将释放多个线程;如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记;如果没有线程在等待,则此事件将保持有标记,直到一个线程被释放。-windowssetevent用法

线程中SetEvent及WaitForSingleObject用法

SetEvent/ResetEvent分别将EVENT置为这两种状态分别是发信号与不发信号。

WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象。

当你创建一个线程时,其实那个线程是一个循环,不像上面那样只运行一次的。这样就带来了一个问题,在那个死循环里要找到合适的条件退出那个死循环,那么是怎么样实现它的呢?

在Windows里往往是采用事件的方式,当然还可以采用其它的方式。在这里先介绍采用事件的方式来通知从线程运行函数退出来,它的实现原理是这样,在那个死循环里不断地使用WaitForSingleObject函数来检查事件是否满足,如果满足就退出线程,不满足就继续运行。当在线程里运行阻塞的函数时,就需要在退出线程时,先要把阻塞状态变成非阻塞状态,比如使用一个线程去接收网络数据,同时使用阻塞的SOCKET时,那么要先关闭SOCKET,再发送事件信号,才可以退出线程的。-windowssetevent用法

当然我感觉重要应用方面还是用来锁定,实现所谓的pv功能。

在调用的过程中,所有线程都可以在一个等待函数中指定事件对象句柄。当指定的对象的状态被置为有信号状态时,单对象等待函数将返回。

对于多对象等待函数,可以指定为任意或所有指定的对象被置为有信号状态。当等待函数返回时,等待线程将被释放去继续运行。

初始状态在bInitialState参数中进行设置。使用SetEvent函数将事件对象的状态置为有信号状态。使用ResetEvent函数将事件对象的状态置为无信号状态。

当一个手动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至明确调用ResetEvent函数将其置为无符号状态。

当事件的对象被置为有信号状态时,任意数量的等待中线程,以及随后开始等待的线程均会被释放。

当一个自动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至一个等待线程被释放;系统将自动将此函数置为无符号状态。如果没有等待线程正在等待,事件对象的状态将保持有信号状态。

多个进程可持有同一个事件对象的多个句柄,可以通过使用此对象来实现进程间的同步。下面的对象共享机制是可行的:

在CreateEvent函数中,lpEventAttributes参数指定句柄可被继承时,通过CreateProcess函数创建的子进程继承的事件对象句柄。

一个进程可以在DuplicateHandle函数中指定事件对象句柄,从而获得一个复制的句柄,此句柄可以被其它进程使用。

一个进程可以在OpenEvent或CreateEvent函数中指定一个名字,从而获得一个有名的事件对象句柄。

使用CloseHandle函数关闭句柄。当进程停止时,系统将自动关闭句柄。当最后一个句柄被关闭后,事件对象将被销毁。一个Event被创建以后,可以用OpenEvent()API来获得它的Handle,用CloseHandle()来关闭它,用SetEvent()或PulseEvent()来设置它使其有信号,用ResetEvent()来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号.-windowssetevent用法

PulseEvent()是一个比较有意思的使用方法,正如这个API的名字,它使一个Event对象的状态发生一次脉冲变化,从无信号变成有信号再变成无信号,而整个操作是原子的.对自动复位的Event对象,它仅释放第一个等到该事件的thread(如果有),而对于人工复位的Event对象,它释放所有等待的thread. 在这个线程函数中只有设置g_event为有信号状态时才执行下面的for循环,因为g_event是全局变量,所以我们可以在别的线程中通过g_event. SetEvent控制这个线程。在这个线程函数中可以可以通过设置MT_INTERVAL来控制这个线程的函数体多久执行一次,当事件为无信号状态时函数体隔MT_INTERVAL执行一次,当设置事件为有信号状态时,线程就执行完毕了。信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号。-windowssetevent用法

TCB中与signal相关数据结构包括active_signal,enable_signal(这是一个掩码,如果为0则不执行signal_handler),(*signal_handler),主要有两个函数,一个是send_signals()和signal_shell(),其中send_signals()函数主要是区分发送信号给自己还是给其他的task,如果发给自己就直接执行signal_shell(),如果发送至其他task(处于suspend或ready但没有占用处理器的状态),target task必须要释放占用的protect,因为在signal_handler中可能会去请求protect资源,这样就会发生死锁,当前task执行TCT_protect_switch()函数,与请求protect()函数前半部分一致,调用schedule_protect()让target task释放占用的protect资源。在target stack处建立solicited stack,其中PC = signal_shell,保存target task的status和tc_statck_ptr,根据当前的状态,如果是ready或pure_suspend,则返回,否则就resume_task()唤醒target task,根据返回值确定是否进入schedule()。NU中支持的线程通信方式包括queue,pipe,mailbox,这里queue和pipe的机制基本相同,只是queue是按32bit操作,pipe是按照字节访问,但是代码里也做了对齐,mailbox是一种信箱机制,信箱的大小为4*32bit,使用的好处就是执行速度快-windowssetevent用法

内存管理

NU并没有使用到虚拟内存管理,直接访问物理地址,有两种建立内存池的方法,动态内存管理和静态内存管理,动态内存管理采用的分配策略是first-fit和释放后内存融合,静态内存管理是每次分配固定大小的内存块,这样可能会引起内存的利用率降低,但是不会引起内存外部碎片-windowssetevent用法

Windows32 Thread API几种共享数据互斥机制可以采用,如何应用

Windows32 Thread API共享数据互斥机制总共有四种:事件(Event)、临界区(Critical section)、互斥量(Mutex)、信号量(Semaphore)。现分别叙述如下:-windowssetevent用法

1、 事件(Event):是WIN32提供的最灵活的线程间同步方式。

使用方法:

用CreateEvent创建一个事件。对于需要手工设置的事件,在需要该事件或者事件发生时,采用SetEvent及ResetEvent来进行设置。

2、临界区(Critical section):防止多个线程同时执行一个代码段。

使用方法:

1) 需要设置临界区时,要先定义临界区对象,采用CRITICAL_SECTION g_cs;

2) 使用前需初始化临界区,采用InitializeCriticalSection(g_cs);函数

3) 需要进入临界区时,采用:EnterCriticalSection(g_cs);函数,从而阻止其他的线程进入。

4) 离开临界区时,采用:LeaveCriticalSection(g_cs);,从而让其他的线程可以进入该临界区。

5) 当该临界区不再有使用价值时,需销毁临界区,采用:DeleteCriticalSection(g_cs);

3、互斥量(Mutex):互斥量通常用于协调多个线程或进程的活动,控制对资源的“锁定”和“取消锁定”,从而控制对共享资源的访问。

使用方法:

1) 首先,建立互斥体对象,得到句柄使用HANDLE CreateMutex()函数;

2) 然后,在线程可能产生冲突的区域前调用WaitForSingleObject函数,将句柄传给函数,请求占用互斥对象:dwWaitResult = WaitForSingleObject(hMutex,5000L); -windowssetevent用法

3) 共享资源访问结束,释放对互斥体对象的占用:ReleaseMutex(hMutex);

4) 最后使用CloseHandle函数删除互斥体对象。

4、信号量(Semaphore):信号对象允许多个有限个数的线程同时访问共享资源。

使用方法:

1) 当需要信号量时要先调用CreateSemaphore函数创建信号量

2) 在需要请求资源时,调用WaitForSingleObject函数或者WaitForMultipleObject函数等待信号量。

3) 资源使用完毕后,调用ReleaseSemaphore函数释放信号量

fabric事件setevent什么时候触发

fabric事件setevent封装好了时候触发。

fabric封装好了画笔功能,我们在使用的时候对画笔进行一些配置即可使用橡皮擦与画笔在使用上基本相同,都是用户使用鼠标进行自由绘画或擦除,所以使用的都是freeDrawingBrush这个api。需要注意的是fabric.js基础库是没有提供橡皮擦模块,我们需要额外引入eraser_brush.mixin.js这个文件。-windowssetevent用法

支持的元操作及task的定义方法,本篇笔记旨在说明如何在多台目标机器上正确地执行tasks以实现远程自动部署或运维。

用法:

直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象。 当你创建一个线程时,其实那个线程是一个循环,不像上面那样只运行一次的。这样就带来了一个问题。

在那个死循环里要找到合适的条件退出那个死循环,那么是怎么样实现它的呢?在Windows里往往是采用事件的方式,当然还可以采用其它的方式。在这里先介绍采用事件的方式来通知从线程运行函数退出来。

windows下的同步机制有哪些

在多线程程序设计中,不可避免地面临着同步问题。在Win32中,有以下四种同步机制。

1、临界区 - Critical Section

(1) 说明

多线程程序中,有些代码是共享资源,需将这些代码作为临界区。如果有多个线程试图同时访问临界区,那么在一个线程进入后,其他线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占。-windowssetevent用法

临界区的同步速度很快;不是内核对象,因而不能跨进程同步;不能指定阻塞时的等待时间(只能无限等待下去)。

(2) 有关函数

操作临界区要涉及的API函数有:

InitializeCriticalSection()

EnterCriticalSection()

LeaveCriticalSection()

DeleteCriticalSection()

这四个函数的形参都是一个指向CRITICAL_SECTION结构体的指针,因而必须先定义一个CRITICAL_SECTION类型的变量。

InitializeCriticalSection()的作用是初始化一个临界资源对象;EnterCriticalSection()的作用是查看CRITICAL_SECTION结构成员变量的值,判断是否有线程访问临界区的资源。如果没有,则更新CRITICAL_SECTION结构成员变量的值,并将当前的线程赋予资源访问权;如果有线程正在访问临界区的资源,则该函数将线程置为等待状态;LeaveCriticalSection()释放临界区资源的所有权,使其他等待临界区资源的线程能够有机会获得临界区资源的所有权。-windowssetevent用法

(3) 应用

#ifndef _ZCZ_WIN32_TOOLS_CCRITICALSECTION_H_

#define _ZCZ_WIN32_TOOLS_CCRITICALSECTION_H_

#include windows.h

namespace zcz_win32_tools

{

class CCriticalSection

{

public:

CCriticalSection();

~CCriticalSection();

public:

void EnterCriticalSection();

void LeaveCriticalSection();

private:

CRITICAL_SECTION m_ObjCriticalSection;

};

class CCriticalSectionOwner

{

public:

CCriticalSectionOwner(CCriticalSection );

~CCriticalSectionOwner();

private:

CCriticalSection m_refCCriticalSection;

};

}

#endif

#include "./CCriticalSection.h"

namespace zcz_win32_tools

{

CCriticalSection::CCriticalSection()

{

::InitializeCriticalSection(m_ObjCriticalSection);

}

CCriticalSection::~CCriticalSection()

{

::DeleteCriticalSection(m_ObjCriticalSection);

}

void CCriticalSection::EnterCriticalSection()

{

::EnterCriticalSection(m_ObjCriticalSection);

}

void CCriticalSection::LeaveCriticalSection()

{

::LeaveCriticalSection(m_ObjCriticalSection);

}

CCriticalSectionOwner::CCriticalSectionOwner(CCriticalSection ObjCCriticalCestion)

:m_refCCriticalSection(ObjCCriticalCestion)

{

m_refCCriticalSection.EnterCriticalSection();

}

CCriticalSectionOwner::~CCriticalSectionOwner()

{

m_refCCriticalSection.LeaveCriticalSection();

}

}

2、互斥量 - Mutex

(1) 说明

互斥对象的作用是保证每次只能有一个线程获得互斥对象而得以继续执行。互斥对象主要包含使用数量、线程ID和递归计数器等信息。其中,线程ID表示当前拥有互斥对象的线程号,递归计数器表示线程拥有互斥对象的次数。-windowssetevent用法

互斥对象是是Windows的内核对象,可跨进程互斥,并且能指定阻塞时的等待时间。

(2) 有关函数

使用互斥对象要涉及的API函数主要有:

CreateMutex() // 创建互斥对象

ReleaseMutex() // 释放互斥对象

OpenMutex() // 跨进程时使用

WaitForSingleObject() // 等待指定时间

使用互斥编程的一般方法是:

void UpdateResource

{

WaitForSingleObject(hMutex,...);

// do something...

ReleaseMutex(hMutex);

}

(3) 应用

#include windows.h

#include iostream

using namespace std;

DWORD WINAPI Fun1Proc(LPVOID lpParameter);

DWORD WINAPI Fun2Proc(LPVOID lpParameter);

int tickets=100;

HANDLE hMutex=CreateMutex(NULL,FALSE,NULL);

void main()

{

HANDLE hThread1,hThread2;

hThread1=::CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);

hThread2=::CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);

::CloseHandle(hThread1);

::CloseHandle(hThread2);

::Sleep(INFINITE);

}

DWORD WINAPI Fun1Proc(LPVOID lpParameter)

{

while (1)

{

WaitForSingleObject(hMutex,INFINITE);

if (tickets0)

{

cout"t1: "tickets--endl;

}

else

{

break;

}

ReleaseMutex(hMutex);

}

return 0;

}

DWORD WINAPI Fun2Proc(LPVOID lpParameter)

{

while (1)

{

WaitForSingleObject(hMutex,INFINITE);

if (tickets0)

{

cout"t2: "tickets--endl;

}

else

{

break;

}

ReleaseMutex(hMutex);

}

return 0;

}

3、事件 - Event

(1)说明

事件是内核对象,具有“激发状态”和“未激发状态”两种状态。事件主要分为两类:

人工重置事件:用程序手动设置。

自动重置事件:一旦事件发生并被处理后,自动恢复到没有时间状态。

(2)有关函数

使用使用事件对象要涉及的API函数主要有:

CreateEvent() // 创建事件对象

SetEvent() // 设置事件对象

ResetEvent() // 设置事件对象

PulseEvent() // 设置事件对象

OpenEvent() // 跨进程时使用

WaitforSingleEvent() // 等待

WaitForMultipleObjects()// 等待

(3)应用

#ifndef _ZCZ_WIN32_TOOLS_CEVENT_H_

#define _ZCZ_WIN32_TOOLS_CEVENT_H_

#include Windows.h

namespace zcz_win32_tools

{

class CEvent

{

public:

CEvent();

~CEvent();

public:

BOOL SetEvent();

BOOL ResetEvent();

BOOL WaitInfinite();

private:

HANDLE m_hEvent;

};

}

#endif

#include "./CEvent.h"

namespace zcz_win32_tools

{

CEvent::CEvent():m_hEvent(NULL)

{

m_hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

}

CEvent::~CEvent()

{

}

BOOL CEvent::SetEvent()

{

if (NULL == m_hEvent || 0 == ::SetEvent(m_hEvent))

{

return FALSE;

}

return TRUE;

}

BOOL CEvent::ResetEvent()

{

if (NULL == m_hEvent || 0 == ::ResetEvent(m_hEvent) )

{

return FALSE;

}

return TRUE;

}

BOOL CEvent::WaitInfinite()

{

if ( WAIT_OBJECT_0 == ::WaitForSingleObject(m_hEvent, INFINITE) )

{

return TRUE;

}

return FALSE;

}

}

4、信号量 - Semaphore

(1)说明

信号量允许多个线程在同一时刻访问统一资源,但是限制了在同一时刻访问共享资源的最大线程数。

信号量是内核对象,允许跨进程使用。

(2)有关函数

使用信号量要涉及的API函数主要有:

CreateSemaphore() // 创建信号量

ReleaseSemaphore() // 释放信号量

OpenSemaphore() // 跨进程使用

在用 CreateSemaphore()创建信号量时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目,不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过 ReleaseSemaphore()函数将当前可用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。-windowssetevent用法

waitforsingleobject()和setevent()的关系

EVENT有两种状态:发信号,不发信号。

SetEvent/ResetEvent分别将EVENT置为这两种状态。

WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象。

《Windows2000核心编程》讲得好些,去图书馆翻翻吧