wxWidgets 2.8线程

wxWidgets可视化框架开发——上 wxWidgets 是一个开源的 C++ 跨平台 GUI(图形用户界面)框架,允许开发者使用同一套代码构建在多个操作系统(如 Windows、macOS、Linux 等)上运行的可视化程序。 阅读详情
 一、thread的创建和终止:
(一)分类:首先知道wxWidgets中的线程分为两种,一是detached的,一是joinable的。
detached: 实现上的方式是,必须创建在堆上,因为,线程对象在你写的线程执行代码结束后(即Entry()返回后),会调用delete this; 来销毁自己。但也允许你手动用“线程.Delete()”来销毁它, 但是同其他的wxWidgets窗体,不允许直接用delete!! 像wxFrame你不用时可以用Destroy(),一样的道理。
          所以,detached,你创建完了之后,不管它,或者不用时调用Delete()!!
joinable: 没有嵌入delete this;,你必须必须!!在其他线程(通常是创建该线程的线程)里,调用"该线程.Wait()",来等待它结束。因为不这样做,线程的资源会永远得不到释放。另外,joinable线程可以创建在栈上或堆上。如果创建在堆上,那么在 Wait 后应该手动用delete释放之。
          所以,joinable,你创建完了之后,一定要Wait,如果在堆上创建,还要delete.

(二) 关于 Delete() 和 Wait() 如何能成功:
上面说道了,Delete() 和 Wait() 可以释放掉 线程 的资源,但是,它们成功的条件是: a 或 b
a:在你写的线程代码,就是虚接口 Entry() 里,必须经常调用 TestDestroy() 函数。如果运行了 TestDestroy,这时,刚好有在Delete()和Wait(),那么线程就会被终止。
b:你写的线程代码,就是 Entry()函数,必须能返回(较快)。返回后,Delete()或Wait()就发挥作用了。

(三) wxWidgets的重要限制 和 线程组模型:
为了对任何情况都能执行成功,禁止非main的线程调用GUI对象相关的函数。
所谓main的线程,就是main()函数的线程,也就是wxApp::OnInit() 函数执行的那个线程。那个线程,在执行完OnInit()后,就转为loop,以处理事件。
然后其他非main线程,虽然你可以在创建的时候,给它某个窗体的指针,让它直接调用之,但是不一定总能成功,这是因为Win32的限制,有些GUI的东西只允许main线程访问。

----------------------------------------------------------------------------------------------------------------------------------
所以,以后编写时,wxWidgets的线程组模型是:
1、main线程就让它跑吧
2、其他线程,可以在wxApp::OnInit()中一块儿创建,如果他们更新GUI,就通过调用继承自wxEvtHandler的窗体,比如wxFrame,wxApp等的AddPendingEvent(wxEvent&)函数。这个函数,只是把事件放到那个窗体对象内部的队列中了,然后返回。真正执行事件处理函数的是主线程。
3、至于所有线程间的同步和共享,虽然可以通过全局的信号量/条件变量, 以及全局的数据区域来完成,但是,我使用局部的信号量/条件变量 和 局部的数据区域,即:在创建子线程的那个线程里(也可能更上层),创建好,再通过线程的构造函数,给线程!!!!
-----------------------------------------------------------------------------------------------------------------------------------


(四) 代码示例:
1、编写自己的线程类:
class MyThread: public wxThread
然后实现虚接口 virtual ExitCode Entry();即写上线程执行的代码,并给出返回码。 //对于joinable的线程,Wait()的返回值等于Entry()的返回值!
注意的是: 默认创建的是detached的,如果你要创建joinable的,则要给基类一个wxTHREAD_JOINABLE参数。
另外,一些本地的变量,如本地的信号量/条件变量,可以从构造函数中传入,然后在Entry()中使用之。
2、创建的代码: 3步让线程跑起来。 new一个,Create() 再 Run()。
MyThread *thread = new MyThread();
if ( thread->Create() != wxTHREAD_NO_ERROR )
{
    die(“Can’t create thread!”));
}
thread->Run();

二、线程控制:
(一) 暂停:
文档中只建议用Sleep(),如果你想睡几分钟。
不建议用可以睡无限久的 Pause 和 Resume,因为有问题。
(二) 互斥和同步:
所有的互斥和同步,都可以基于“信号量”来做。 一种同步用“条件变量”来做会更概念清晰。
概述:
像生产者和消费者的问题: 生产者和消费者之间需要同步,生产者和生产者/消费者和消费者之间需要互斥(如果采用链表而不是数组,那么生产者和消费者之间也需要互斥)。 不管是互斥还是同步,都可以用信号量来做。Mutex的目的是:专用于互斥,让概念清晰。而在具体机制上和信号量不同的是:
     一个线程用wxMutex::Lock()住的东西, 另一个线程不能Unlock,这就是Mutex不能用于同步的原因!

1、信号量和互斥锁:
a. wxSemaphor:计数信号量。你创建一个这样的对象,其value值默认初始为0。就可以调用wxSemaphor::Wait —— 对应P原语,wxSemaphor::Post —— 对应V原语。具体场景在下面wxMutex中说了一下。
b. wxMutex: 信号量的变体。用法很简单,你创建一个wxMutex的实例,并把它的地址作为构造函数参数给其他创建的线程。然后当很多线程都要写一个公共的东西时,先调用wxMutex::Lock(),然后才访问那个东西,用完后再wxMutex::Unock()即可。TryLock()可以测试lock,如果不能lock,不会阻塞。 这个东西因为很方便,所以挺好。它有一个更方便的,使用"资源管理器"的思想,就是:如果一段函数代码不允许重入(临界区),那么可以在开头放上:wxMutexLocker lock(wxMutex对象)即可,不必Lock再Unlock,它在构造函数里试着去调用wxMutex::Lock()。但是为了防止小可能的Lock错误,在之后最好调用IsOK(),再进行操作:
wxMutexLocker lock(m_mutex);
if (lock.IsOk()) {
   ...
}


2、条件变量:
用到条件变量的地方,是因为有一种情形,用信号量概念上不太清晰(虽然可以)
试想: 一个主线程,开启了若干线程,然后,它想控制若干线程同时运行,就是比如发了一个信号,大家都开始运行(也就是说,大家都在等待一个条件)。如果用信号量来做的话,需要准备若干个信号量,然后在那些子线程构造的时候赋给他们,然后用这么多信号量来控制这么多线程的同时运作。 或者让若干进程都等在一个信号量上,然后主线程突然改变信号量的值到若干线程的数目,然后那些若干进程,都可以跑了。

所以:为了概念清晰,引入条件变量wxCondition。也是将其对象的地址作为构造函数参数给那些若干线程。然后大家要等的话,都调用wxCondition::Wait()。而主线程,可以调用wxCondition::Signal()来通知任一线程运行(不确定是哪个),也可以调用wxCondition::Broadcast()来通知所有的线程开始运行。

但是:同pthread存在的问题一样,用条件变量引入了两个复杂性:
1、条件变量被很多线程修改,因此必须用信号量(wxMutex)来保护。
2、可能主线程运行的快,他先Signal了,而若干线程之后才Wait,这样导致信号丢失! 因此这里还要设置一个信号量(wxMutex)来使得Wait一定发生在Signal之前。

总之,1这个情况是肯定要考虑到的,至于2,可以用变通的办法,比如让主线程在Signal之前,先等待很久。


三、线程的替代:
很多情况下,不用线程,就可以实现,而且实现的更好。
1、wxIdleEvent:
这个Event的就是所谓的Idle Event,别理解错了,它并不是说周期性的发送,而是说,当一个用户事件(控件)处理完毕后,产生一个Idle Event.这个事件将发往wxApp对象和所有的窗体对象。如果你要捕获它,写法如下,记得把事件Skip,因为原本你不是处理者。其中,注意到RequestMore,他使得Idle被重发给自己,如果你不请求这个,那么下一次Idle,又只有到下一个用户事件处理完毕后。
class MyFrame : public wxFrame
{
public:
    ...
    void OnIdle(wxIdleEvent& event);
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_IDLE(MyFrame::OnIdle)
END_EVENT_TABLE()
void MyFrame::OnIdle(wxIdleEvent& event)
{
    // Do idle processing, ask for more idle
    // processing if we haven’t finished the task
    if (!FinishedIdleTask())
        event.RequestMore();
    event.Skip();
}

2、真正的周期信号 wxTimer:
如果你不满意Idle那种,那就用wxTimer吧。
用法: 做接收wxTimerEvent的函数,这里,MyFrame作为wxEvtHandler,提供了一个OnTimer的函数。并写好事件表。至于具体的timer,你可以在任意地方生成。
只不过要注意,timer事件到底给谁,你就要用谁作为timer的构造函数的参数(或用wxTimer::SetOwner来设置)。另外,还要给这个Timer一个ID,这样在写MyFrame的事件表的时候,可以指定来自哪个timer。
#define TIMER_ID 1000
class MyFrame : public wxFrame
{
public:
    ...
    void OnTimer(wxTimerEvent& event);
private:
    wxTimer m_timer;
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_TIMER(TIMER_ID, MyFrame::OnTimer)
END_EVENT_TABLE()
MyFrame::MyFrame()
        : m_timer(this, TIMER_ID)
{
    // 1 second interval
    m_timer.Start(1000);
}
void MyFrame::OnTimer(wxTimerEvent& event)
{
    // Do whatever you want to do every second here
}


3、Yielding: 这个文档建议不用。

wxWidgets多线程编程基础 一、thread的创建和终止: (一)分类:首先知道wxWidgets中的线程分为两种,一是detached的,一是joinable的。 detached: 实现上的方式是,必须创建在堆上,因为,线程对象在你写的线程执行代码结束后(即Entry()返回后),会调用delete this; 来销毁自己。但也允许你手动用“线程.Delete()”来销毁它, 但是同其他的wxWidgets窗体,不允 阅读详情

相关推荐

wxWidgets多线程及事件传递

前言 ​ 最近忙着写项目,wxWidgets计划还有wxWidgets日志系统的拦截重定向,剩下一些比较杂的知识点,想到哪写到哪。比如进程间通信、调用外部程序后结束本程序(用于升级程序)、集成带窗口的ActiveX、创建单进程程序等,这些文档上基本都有。下面开始多线程的应用。 代码示例 ​ 废话不多说,此示例演示,子线程进程业务处理完之后通知主线程,等待主线程执行完,子线程接着处理业务的过程。 ​ 主要内容在主窗口文件和线程文件里面 ​ 主窗口头文件: /**************************

q893332169的博客 1620

【wxWidgets 教程】安装、配置、HelloWorld篇(一)

wxWidgets 3.2 使用 CMake 进行安装、配置,并用其编写一个最基本的项目。

Xiao_Ley的博客 1万+

wxWidgets事件机制详解

wxWidgets事件机制详解全篇

weixin_43484713的博客 1263

【2026.03.06】马年新春版 - 定时执行专家V8.0发布 - TimingExecutor V8.0 Release

《定时执行专家》是一款专业级定时任务软件,支持135种任务类型和12种触发方式,提供毫秒级执行精度,可同时处理200+任务。最新V8.0版本更新了界面图标和GUI框架,采用wxWidgets3.2.10开发。软件持续迭代优化,如V7.6升级框架、V7.5修复显示问题等。用户可通过优快云博客获取最新版本和详细更新日志。

boom's works 344

wxWidgets 的全面介绍及使用方法

开发者可以直接使用已有的控件和事件处理程序,或自己编写新的控件和事件处理程序,快速构建一个完美的界面。它提供了一套完整的工具包,包括控件、类、事件处理程序等,可以让开发者轻松地开发 GUI 应用程序,而不需要重新编写代码以适应每个平台。总之,wxWidgets 是一个非常强大、简单易用的 C++ 库,用于创建跨平台的 GUI 应用程序。wxWidgets 中的控件非常丰富,包括按钮控件、文本框控件、列表框控件等等,开发者可以根据自己的需求选择合适的控件来构建界面。wxWidgets 的全面介绍及使用方法。

uote_e的博客 2123

wxWidgets:创建和管理用户界面的强大工具

wxWidgets是一个开源的C++图形用户界面(GUI)库,它提供了一套跨平台的工具和类,用于创建和管理用户界面。wxWidgets是一个强大的工具,它提供了丰富的类和功能,使开发者能够轻松创建跨平台的用户界面。我们首先了解了安装和配置wxWidgets的基本步骤,然后通过一个简单的示例演示了如何创建一个基本的窗口应用程序。在MyApp的OnInit函数中,我们创建了一个MyFrame的实例,并显示出来。下载wxWidgets:访问wxWidgets官方网站,下载稳定版本的wxWidgets库。

TechO_O的博客 1150

wxWidgets开发之线程wxThread

这节分享一下wxWidgets中的线程开发。在wxWidgets中有两种类型的线程:分离式跟联合,它们模仿POSIX线程API实现。如果我们查阅wxWidgets线程源码会发现如下几个win32线程API接口函数,就知道了其实我们对wxWidgets线程开发本质就是对win32开发。 HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPT

小桥留水人家 1337

wxWidgets 线程示例

wxWidgets 线程示例wxWidgets 线程示例 wxWidgets 线程示例 #include "wx/wxprec.h" #ifndef WX_PRECOMP #include "wx/wx.h" #endif #if !wxUSE_THREADS #error "This sample requires thread support!" #endif // wxUSE_THREADS #include "wx/thread.h" #include "wx/dynarray.h"

希望我的博客,能帮上你解决学习中工作中所遇到的问题 1171

wxWidgets简单的多线程

#include <wx/wx.h> #include <wx/thread.h> #include <wx/event.h> #include <wx/progdlg.h> #include <wx/gauge.h> class MyApp : public wxApp { public: virtual...

weixin_34250709的博客 1221

wxWidgets多线程概述

在这个示例中,我们定义了一个名为condition的wxCondition对象,并在Thread1()中使用它等待Thread2()信号。在这个示例中,我们创建了一个名为MyThread的自定义线程类,它继承自wxThread类,并重写了Entry()函数。创建和启动线程的过程非常简单。我们创建一个MyThread对象,调用它的Create()方法创建线程,然后调用它的Run()方法启动线程。wxMutex是另一个重要的多线程类,它提供了一种同步机制,用于确保只有一个线程可以访问某个资源。

SVIPCODE的博客 438

wxWidgets:多线程概述

wxWidgets:多线程概述wxWidgets:多线程概述多线程应用程序的重要说明 wxWidgets:多线程概述 wxWidgets 提供了一套完整的类封装了多线程 (MT) 应用程序中必需的对象:wxThread类本身和不同的同步对象:互斥锁(wxMutex)和临界区(wxCriticalSection)和条件(wxCondition)。 wxWidgets 中的线程 API 类似于 POSIX1.c 线程 API(又名 pthreads),尽管几个函数具有不同的名称,并且也有一些受 Win32 线程

希望我的博客,能帮上你解决学习中工作中所遇到的问题 964

wxWidgets介绍 —— 一文全面了解wxWidgets

wxWidgets由爱丁堡大学的Julian Smart于1992年创立。最初是一个用于创建在Unix和Windows上可移植的应用程序的项目,后来它已成长为支持MacOS,GTK+以及许多其他工具包和平台的界面库(有关更多详细信息,请参见“历史”页面)。为该项目做出贡献的开发人员数量现在为数百人,工具包也有强大的用户群,其中包括从开源开发人员到公司开发人员等很多人。那么,与其他跨平台GUI工具包相比,wxWidgets有什么特殊之处?

boom's works 8532

WxWidgets 2.8 示例项目详解与实践

本文还有配套的精品资源,点击获取 简介:WxWidgets 是一个C++跨平台GUI库,支持Windows、Linux、macOS等操作系统。它提供丰富的GUI组件和布局管理器,实现复杂用户界面。本示例项目包含基础控件使用、事件处理、对话框和菜单设计、高级组件应用、文件操作与网络通信、数据库访问、国际化和本地化支持、图形和多媒体功能集成以及调试和性能优化等。这些示例有助于开...

weixin_33562004的博客 2394

多线程小测(一)(wxWidgets)

梁淇(C/C++) 1499

wxWidgets 2.8.12官方完整版跨平台GUI开发库实战

wxWidgets 是一个开源、跨平台的 C++ 框架,旨在为开发者提供一套统一的 API 来构建原生外观的图形用户界面(GUI)应用程序。wxWidgets 2.8.12 是该框架在稳定演进过程中的一个重要版本,广泛应用于桌面级应用开发,尤其适用于需要同时支持 Windows、Linux 和 macOS 的项目。关键头文件位于下::定义wxApp抽象类,应用程序入口点:定义wxFrame,主窗口类:所有可视控件的基类:事件处理机制核心。

weixin_35364187的博客 535

C#实践项目1

需求: 在CAD内实现两个坐标系的转换。 转换方式为文件内的所有图形从一个坐标系下的坐标,转换到另一个坐标系下的坐标。 进行坐标转换后,仅仅是坐标发生改变,图层、样式等等不会发生变化。

weixin_51182789的博客 5323

告别Visual Studio和QT:用VSCode + MinGW + CMake轻量级搭建wxWidgets 3.2.1开发环境

本文详细介绍了如何使用VSCode、MinGW和CMake轻量级搭建wxWidgets 3.2.1开发环境,替代传统的Visual Studio和QT方案。通过模块化工具选择和纯文本配置,显著降低资源占用,提升开发效率。文章涵盖环境配置、源码编译、VSCode高效设置及性能对比,为C++开发者提供现代化工作流解决方案。

痴迷无限好 1122

随机化策略——随机变量rand、约束constraint、权重dist、随机数产生示例

文章目录一、随机变量类型1.1.rand随机变量1.2.randc随机变量二、随机化约束2.1.constraint指定约束范围2.1.1.关系操作符约束(>、<、=、>=、<=)2.1.2.范围操作符约束(inside)2.1.3.权重分布约束(dist)2.1.4.条件约束(if-else; ->)三、启动随机化——randomize( )函数四、关闭或打开随机变...

Mr.翟的博客 2万+
上一篇: 为什么C++编译器不能支持对模板的分离式编译
下一篇: vc检测USB设备插入或移除
embededvc
博客等级 码龄21年 176粉丝 41原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值