当前位置: 首页 > news >正文

惠州禅城网站建设安徽百度关键词优化

惠州禅城网站建设,安徽百度关键词优化,网络热词有哪些,如何建设网站步骤进程/线程通信的方式 某些应用程序中#xff0c;进程/进程和线程/线程之间不可避免的进行通信#xff0c;进行消息传递#xff0c;数据共享等 同一进程的线程之间通信方式包括Windows中常用Event, Message等。 不同进程之间的通信可以利用Event, FileMapping(内存共享), W…进程/线程通信的方式 某些应用程序中进程/进程和线程/线程之间不可避免的进行通信进行消息传递数据共享等 同一进程的线程之间通信方式包括Windows中常用Event, Message等。 不同进程之间的通信可以利用Event, FileMapping(内存共享),  WM_COPYDATA消息以及ClipBoard(剪贴板)DDE, MessagePipe, MailSlot(邮件槽等 在Tron系统中除了支持Event之外还支持MailBox,MessageBuffer等通讯手段 使用事件进行通信 事件除了用来保证两个线程之间同步之外借由通知功能也可以作为线程之间的简单通信的手段 线程使用WaitForSingleObject等待一件事情的发生该事情可以由另外一个线程通过SetEvent进行触发。 使用WaitForMultipleObjects等待多个由其他线程触发的事件某些情况下在线程的函数中也给自己发送消息 事件只能通知一件事情的发生不能传递其他附属数据。 通知事件  调用SetEvent, 可以将事件的内核对象的状态变成 已通知  调用ResetEvent, 可以将事件的内核对象的状态变成 未通知  调用PulseEvent, 将事件对象置为有信号状态然后立即置为无信号状态在实际开发中这个函数很少使用  不同进程之间也可以通过Event通知事件这可以通过命名对象来实现CreateEvent时指定了名称不同进程之间通过创建同名的Event就可以获得指向同一个内核对象的句柄这样不同进程间就可以互相通知和等待Event 使用事件通知并传送数据 Event可以通知一件事情, 但是不能同时传送数据, 可以采用几种方式异步的获得数据. 先设置给接收方数据, 后通知Event.     由接收Event方提供设置(保存)数据的函数, 在接收方接受到通知后, 从自己保存的数据中取得数据. 先通知Event后从发送方取得数据 使用Event做成消息队列     在接收方做成一个存储消息和数据的队列, 每次登录一个消息(数据)后,通知接收方, 接受方从该队列中顺序取得数据. Windows消息 Windows是一个消息Message驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发并且靠对消息的响应和处理来完成。 Windows系统中有两种消息队列系统消息队列和应用程序消息队列。计算机的所有输入设备由Windows监控。当一个事件发生时Windows先将输入的消息放入系统消息队列中再将消息拷贝到相应的应用程序消息队列中。应用程序的消息处理程序将反复检测消息队列并把检测到的每个消息发送到相应的窗口函数中。这便是一个事件从发生至到达窗口函数必须经历的过程。 必须注意的是消息并非是抢占性的无论事件的缓急总是按照到达的先后派对依次处理一些系统消息除外这样可能使一些实时外部事件得不到及时处理 用户界面线程和工作线程 Windows中存在两种线程一种是用户界面线程一种是工作线程。 工作线程线程是用来执行某些辅助处理的线程它不需要进行任何系统事件或者窗口事件的处理。 用户界面线程是指拥有自己的消息循环并能对用户界面对象进行创建、交互和撤销的线程。 Windows的消息机制与用户界面线程息息相关。用户界面线程一般是继承CWinThread类实现。 一个线程被创建后系统假定线程不会被用于任何与用户相关的操作 一旦一个线程调用一个与图形用户界面有关的函数(如创建窗口或者检查消息队列的函数Windows会分配给这个线程一个THREADINFO结构。 线程的消息队列 每个线程利用THREADINFO来认为自己是在一个独占的环境中运行。在这个结构里保存了一系列的消息队列登记消息队列、发送消息队列、应答消息队列、唤醒标志、以及用来描述线程局部输入状态的若干变量。 THREADINFO结构是窗口消息系统的基础 当线程有了与之相联系的THREADINFO的结构时线程就有了自己的消息队列集合 Windows消息结构介绍 消息结构如下  typedef struct tagMSG  {   HWND   hwnd ;      UINT    message ;      WPARAM    wParam ;      LPARAM    lParam ;      DWORD    time ;      POINT pt ;  }MSG, * PMSG ; hwnd 接收消息的窗口句柄。 message 消息种别。这是一个数值用以标识消息。对於每个消息息均有一个对应的识别字这些识别字定义在Windows头文件中其中大多数在WINUSER.H中以字首WM开头。 例如使用者将鼠标窗口内并按下左按钮Windows就在消息队列中放入一个消息该消息的message成员的值是WM_LBUTTONDOWN。这是一个常数其值为0x0201。 wParam 一个32位的参数其含义和数值根据消息的不同而不同。  lParam 一个32位的消息参数其值与消息有关。 time消息放入消息队列中的时间。 pt消息放入队列时的鼠标座标。  用户使用自定义的消息的时候, 可以充分利用lParam,和 wParam传递数据 将消息发送到线程的消息队列中 通过PostMessage把消息发送给窗口所在的线程     PostMessage(HWND hWnd,UINT uMsg,             WPARAM wParam,LPARAM lParam) -当一个线程调用了这个函数的时候系统要确定时哪一个线程建立了用hWnd参数标志的窗口 -系统分配内存存储消息参数将这块内存增加到相应线程的消息队列中 -系统设置QS_POSTMESSAGE唤醒位标志 通过PostThreadMessage将消息放置在线程的消息队列 PostThreadMessage(DWORD dwThreadId,UINT uMsg,WPARAM wParam, LPARAM lParam) -可以通过GetWindowThreadProcessID来确认是哪个线程创建了窗口 -ThreadID是在线程创建的时候获得的在全系统范围内是唯一的 -要对线程编写消息循环GetMessagePeekMessage,DispatchMessage) -PostQuitMessageint nExitCode向线程发送退出消息等于PostThreadMessage(ThreadID,WM_QUIT,nExitCode,0); PostMessage和SendMessage 当我们使用PostMessage时是将一个Message复制到“登记消息队列”中然后并立即返回。之后由GetMessage取回并响应之。 当我们使用SendMessage时我们都知道这个消息发送函数必须等到消息响应执行完毕才能返回。而它如何做到这一点的呢当调用这个SendMessage的线程向这个线程自己创建的窗口发送消息的时候它只是调用指定窗口的窗口过程将其作为一个子例程当窗口过程完成对消息的处理时返回给SendMessage一个值。当一个线程向其他线程创建的窗口发送消息的时候SendMessage首先将消息加入接收线程的“发送消息队列”并为这个线程设置标志。同时发送线程将自己挂起并在自己的“应答消息队列”中加入一个等待消息。当消息被接收线程处理完毕后窗口的返回值被登记到发送线程的应答消息队列中。这是发送线程被唤醒取出包含在应答消息队列中的返回值。 取得窗口消息 使用GetMessage或者PeekMessage取得窗口的消息 一个典型而普通的消息循环处理 while(GetMessage(msg,NULL,0,0)) {         TranslateMessage(msg);         DispatchMessage(msg); } 这段处理必然实在用户界面线程的主循环中完成的 GetMessage的特点是当线程消息队列中有消息的时候则能立刻返回否则进行等待 PeedMessage也能从线程消息队列中取得消息它的特点是不管消息队列是否存在消息都不等待。 CWinApp处理消息 MFC应用程序都有一个CWinApp对象继承于CWinThread在CWinApp的Run函数中进行了和GetMessage和DispatchMessage的处理,可以在MFC源代码THRDCORE.cpp找到CWinThread::Run()的代码以及Run函数的运行时机。 同时等待消息和内核对象 某些情况下你的线程不得不等待一个或多个事件并且同时等待某些Message。 MsgWaitForMultipleObjects函数非常类似WaitForMultipleObjects,但它会在“对象被激发”或者”消息到达队列”时被唤醒并且返回 DWORD MsgWaitForMultipleObjects(         DWORD nCount,          // 等待内核事件的个数         LPHANDLE pHandles,     // 内核事件对象数组指针         BOOL    fWaitAll,          // 是否等待全部事件才返回         DWORD dwMilliseconds,// 超时值         DWORD dwWakeMask); // 唤醒Mask MsgWaitForMultipleObjects MsgWaitForMultiObjects的前四个参数和WaitForMultipleObjects完全相同 参数dwWakeMask指出了想要观察的用户输入Message     QS_ALLINPUT     QS_HOTKEY     QS_INPUT     QS_KEY     QS_MOUSE     QS_MOUSEBUTTON     QS_MOUSEMOVE     QS_PAINT     QS_POSTMESSAGE     QS_SENDMESSAGE     QS_TIMER 为了表达”消息到达队列“返回值将是     WAIT_OBJECT_0nCount MsgWaitForMultipleObjects代码实例 DWORD WINAPI ThreadFunc(LPVOID lpParam)  {    bool bRun true;     while(bRun) {         dwRet MsgWaitForMultipleObjects(nEventCount,                    HandleArray,    // event handle array              FALSE,        // 只要有一个事件触发就可以返回             dwMilliseconds,    // 超时值             QS_ALLINPUT );    // 等全部消息         if (WAIT_FAILED dwRet ) {// 错误处理}         if (WAIT_TIMEOUTdwRet{// 超时处理}         if (WAIT_OBJECT_0nEventCountdwRet) {             while(PeekMessage(Msg,NULL,0,0,PM_REMOVE) {             // 做消息处理             }         } else{             switchdwRet-WAIT_OBJECT_0) {             case EVENT_EVT1:             // 处理事件1             break;             //...... 其它事件处理             }         }     } } Event和Message Event会覆盖(丢失), Message不会 Event只能通知一件事情的发生,不能传送数据,Message可以传递简单的数据(通过LParam和WParam) 在同一个进程内, Message可以通过LParam或者WParam指向一个堆内存而达到数据通信的功能. 发Event需要指定目标Handle, 发Message需要指定目标Window(窗口句柄) Event可以跨越进程, 通过名字达到共享. Message也可以跨越进程, 通过注册消息(RegisterWindowMessage ), 在进程间共享消息. 进程间通信自定义消息 在某些情况下我们可能需要向其他的应用程序发送消息这时候我们可以采用SendMessage()函数向目标应用程序的某个窗口的句柄发送消息。其中的技巧在于获取该窗口的句柄。同时使用RegisterWindowMessage()函数创建一个唯一的消息并且两个应用程序相互都了解这条消息的含义。同时还会用到BrodcastSystemMessage()函数它可以向系统中的每个应用程序的主窗口发送消息。这样便可以避免出现获取另一个应用程序窗口句柄的问题。BroadcastSystemMessage()函数提供了附加的标志BSF_LPARAMPOINTER可以将写入参数lParam的指针转化为可以被目标程序用来访问程序空间的指针但是这个标志可能尚未进行文档标准化。 方法如下     首先注册自己的窗口消息。不过我们这次不用WM_USER1的技术注册窗口消息的好处是不必费心考虑WM_USER加上某个数之后所表示的消息标识符是否超出工程的允许范围。本例在两个工程中都使用文本字符串来注册消息。由于这个文本字符串在整个系统中应当是唯一的因此将使用一种称为GUID的COM技术来命名消息。GUID名字生成器程序可以在MFC的\BIN目录下找到其可执行文件名为GUIDGEN.EXE。该程序将生成在应用程序已知范围内认为是唯一的文本字符串这对应用程序来说当然是最好不过的。 1) 注册一个唯一的窗口消息 使用GUIDGEN.EXE生成一个GUID。 在应用程序中把GUID定义为窗口消息文本字符串:#define HELLO_MSG “{6047CCB1-E4E7-11d1-9B7E-00AA003D8695}” 使用::RegisterWindowsMessage()注册该窗口消息文本字符串:idHelloMsg ::RegisterWindowMessage( HELLO_MSG ); 保存消息标识符idHelloMsg便于以后使用。 2) 向其他应用程序发送消息 使用::RegisterWindowsMessage()返回的消息标识符发送消息可使用以下代码: ::SendMessage(hWnd, idHelloMsg,wParam,lParam); 以上代码假定事先可以通过某种方式获取目标应用程序的某个窗口的句柄。一个指向CWnd类的指针不能在程序范围之外而发挥作用。但是可以在CWnd 类中封装已获取的窗口句柄并如下所示来发送消息 CWnd wnd; wnd.Attach( hWnd ); wnd.SendMessage( idHelloMsg,wParam,lParam ); 3) 接收已注册的窗口消息 为接收已注册的窗口消息需要在接收窗口类一般为CMainFrame中手工添加ON_REGISTERED_MESSAGE消息宏到消息映射中: BEGIN_MESSAGE_MAP( CMainFrame, CMDIFrameWnd ) // {{AFX_MSG_MAP( CMainFrame ) // }}AFX_MSG_MAP ON_REGISTERED_MESSAGE( idHelloMsg,OnHelloMsg ) END_MESSAGE_MAP() 有关已注册消息的消息处理函数的代码如下 LRESULT CMainFrame::OnHelloMsg( WPARAM wParam,LPARAM lParam ) { // process message return 0; } 该实例到目前为止一直假定事先可以通过某种方式取得目标应用程序的某个窗口的句柄。但这是一个困难的任务。简单的方法是向每个应用程序广播一条消息并且希望目标程序正在监听。由于在系统中注册了一条唯一的消息因此只有目标程序会响应这条消息。应用程序广播的消息可能是它自己的窗口句柄于是接收程序可以使用::SendMessage()来发送应答也可能是用窗口句柄来结束循环。 4) 广播窗口消息 使用下面的代码广播窗口消息 WPARAM wParam xxx;  LPARAM lParam xxx; DWORD dwRecipients BSM_APPLICATIONS; ::BroadcastSystemMessage( BSF_IGNORECURRENTTASK,dwRecipients,idHelloMsg,wParam,lParam );  进程间通信WM_COPYDATA 通过SendMessage可以把一个消息发送到另外一个进程但是在另外一个进程中试图访问LPARAM所指向的数据也许会发生错误 进程地址空间是受到保护和相互隔离的视图访问另外一个进程的地址空间是不正确的。 Windows定义了WM_COPYDATA消息专门用来在线程之间传递数据,不管两个线程是否属于一个进程 处理WM_COPYDATA的线程必须有消息队列和窗口带有消息队列的工作线程或者UI主线程) SendMessage(hWndReceiver,                 WM_COPYDATA,                 (WPARAM)hWndSender,                 (LPARAM)cds); LPARAM 参数cds指向一个特定的Windows数据结构COPYDATASTRUCT typedef struct tagCOPYDATASTRUCT{     DWORD dwData;//通常用户自定义为行动代码     DWORD cbData;// lpData所指的数据块大小     PVOID lpData; // 一块数据可以被传送到接受端 }COPYDATASTRUCT,*PCOPYDATASTRUCT; 必须使用SendMessage而不是PostMessage发送WM_COPYDATA消息 WM_COPYDATA所传送的数据可以在Heap上也可以在Stack上申请因为SendMessage保证接收方在返回前完成对数据的操作。 接受方必须在WM_COPYDATA消息处理函数中完成对lpData的处理读取和保存其中的内容而不是保存lpData指针对接收方来说在这次消息处理后lpData所指向的内存将不再是可用的。 进程间通信共享内存(SharedMemory) Win32进程之间有严密的保护一个进程要看到另外一个进程的地址空间中的任何一部分都是不可能的。 程序只能见到逻辑的地址所有进程的逻辑地址空间都是相同的(4GB的理论地址空间) WM_COPYDATA技术简单但是效率不高 使用Win32进程通信技术的最低层:共享内存(SharedMemory)来进行高效的进程间数据共享 使用共享内存的方法 1.设定一块儿共享内存 2.使用共享内存 3.同步处理共享内存 设定共享内存块 1. 产生一个FileMapping内核对象指定共享区域大小CreateFileMapping 2. 将共享区域映射到你的进程的地址空间     (MapViewOfFile) 找到共享内存块     有些情况下由Server进程创建一个共享内存其他进程只需要找到这块共享内存并使用就可以了。 1. 找到一个FileMapping内核对象使用OpenFileMapping     系统找到同一个FileMapping内核对象是根据 对象的命名 2. 将共享区域映射到你的进程的地址空间    (MapViewOfFile) 同步使用共享内存     多个进程使用共享内存的时候必须保证同步安全的使用共享的内存通常使用等待被命名的Mutex来保证。 创建共享内存CreateFileMapping HANDLE CreateFileMapping(   HANDLE hFile,                   //物理文件句柄   LPSECURITY_ATTRIBUTES lpAttributes, //安全设置   DWORD flProtect,                    //保护设置   DWORD dwMaximumSizeHigh,  //高位文件大小   DWORD dwMaximumSizeLow,  //低位文件大小   LPCTSTR lpName                    //共享内存名称 ); 1) 物理文件句柄    任何可以获得的物理文件句柄, 如果你需要创建一个物理文件无关的内存映射也无妨, 将它设置成为 0xFFFFFFFF(INVALID_HANDLE_VALUE)就可以了.    如果需要和物理文件关联, 要确保你的物理文件创建的时候的访问模式和“保护设置”匹配, 比如: 物理文件只读, 内存映射需要读写就会发生错误. 推荐你的物理文件使用独占方式创建.    如果使用 INVALID_HANDLE_VALUE, 也需要设置需要申请的内存空间的大小, 无论物理文件句柄参数是否有效, 这样 CreateFileMapping 就可以创建一个和物理文件大小无关的内存空间给你, 甚至超过实际文件大小, 如果你的物理文件有效, 而大小参数为0, 则返回给你的是一个和物理文件大小一样的内存空间地址范围.  返回给你的文件映射地址空间是可以通过复制, 集成或者命名得到, 初始内容为0. 2) 保护设置    就是安全设置, 不过一般设置NULL就可以了, 使用默认的安全配置. 在win2k下如果需要进行限制, 这是针对那些将内存文件映射共享给整个网络上面的应用进程使用是, 可以考虑进行限制. 3) 高位文件大小    目前我们的机器都是32位的, 不可能得到超过32位进程所能寻址的私有32位地址空间, 一般还是设置0. 4) 低位文件大小    实际共享内存的大小, 不过为了让其他共享用户知道你申请的文件映射的相关信息, 使用的时候是在获得的地址空间头部添加一个结构化描述信息, 记录内存映射的大小, 名称等。 5) 共享内存名称    在其他进程创建同名的共享内存的时候系统会返回存在的共享内存. 映射共享内存MapViewOfFile LPVOID MapViewOfFile(     HANDLE hFileMappingObject,     DWORD dwDesiredAccess,     DWORD dwFileOffsetHigh,     DWORD dwFileOffsetLow,     DWORD dwNumberOfBytesToMap);  MapViewOfFile()函数负责把文件数据映射到进程的地址空间。     hFileMappingObject为CreateFileMapping()返回的文件映像对象句柄。dwDesiredAccess则再次指定了对文件数据的访问方式而且同样要与CreateFileMapping()函数所设置的保护属性相匹配。     MapViewOfFile()函数允许全部或部分映射文件在映射时需要指定数据文件的偏移地址以及待映射的长度。其中文件的偏移地址由DWORD型的参数dwFileOffsetHigh和dwFileOffsetLow组成的64位值来指定而且必须是操作系统的分配粒度的整数倍对于Windows操作系统分配粒度固定为64KB。当然也可以通过如下代码来动态获取当前操作系统的分配粒度          SYSTEM_INFO sinf;     GetSystemInfo(sinf);     DWORD dwAllocationGranularity sinf.dwAllocationGranularity;  MapViewOfFile的返回值就是被映射在进程地址空间中的共享内存块指针用户操作这个指针可以达到共享内存了。 使用共享内存-Create/OpenFileMapping 共享内存以点对点peer to peer)的形式呈现     则每个进程都必须有相同的能力产生共享内存并将它初始化。每个进程 都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的错误代码是ERROR_ALREADY_EXISTS,     那么进程就可以假设这一共享内存区域已经被别的进程打开并初始化了否则该进程就可以合理的认为自己 排在第一位并接下来将共享内存初始化。         共享内存以client/server架构的形式呈现     只有server进程才应该产生并初始化共享内存。所有的进程都应该使用由OpenFileMapping得到的共享内存映射文件。     HANDLE OpenFileMapping(DWORD dwDesiredAccess,                                        BOOL bInheritHandle,                                        LPCTSTR lpName);     其中lpName是其他进程用CreateFileMapping函数创建共享内存时时指定的对象名称。     再调用MapViewOfFile(),取得共享内存的指针
http://www.zqtcl.cn/news/745645/

相关文章:

  • 网站制作可以询价么168推广
  • 河南城乡和住房建设厅网站网络营销的主要特点有哪些
  • 哪些网站可以做自媒体wordpress 左侧
  • joomla! 1.5 网站建设基础教程丹阳网站推广
  • 中国建设银行山东省分行网站怎么做网站制作
  • 网站前台设计方案自助建站一般适用于大型电子商务网站建设
  • 建设银行不良资产处置网站wordpress啥时候出现的
  • 出口贸易网站网站建设及解决方案
  • 网站服务器要求做网站需要的服务器
  • 网站后台 编辑器 调用网站优化搜索排名
  • 汽车网站建设规划书网站首页版式
  • 国外网站推广方法wnmp 搭建WordPress
  • 网站建设流程 文档企业网上办事大厅
  • .net怎么做网站域名备案注销流程
  • 检测网站建设网站搭建注意事项
  • 河北建设工程信息网站网站的建设要多少钱
  • 玉林住房和城乡建设局网站官网google广告在wordpress
  • 海淀网站建设公司wordpress 招聘网站模板
  • 手机网站在哪里找到网上能免费做网站发布叼
  • 网站设置英文怎么说广州优质网站建设案例
  • 外贸怎样做网站临汾花果街网站建设
  • 专业集团门户网站建设方案南昌医院网站建设
  • 用php做美食网站有哪些新建网站如何做关键词
  • 企业网站建设招标微信公众平台官网登录入口网页版
  • 网站宣传图网站程序预装
  • 网站设计论文选题seo排名优化推广报价
  • wordpress图床网站百度链接收录
  • 八年级信息网站怎么做电商网站的支付接入该怎么做呢
  • wordpress 的应用大兴安岭地网站seo
  • 网站建站作业做直播网站赚钱