Mint_21.3 drawing-area和goocanvas的FB笔记(三)

一、改变goocanvas线条自动画线时间间隔

通过系统SIGALRM信号触发,每秒画一条线对于慢温湿度等慢变信号可以应付,但对于快速信号1秒的间隔就太慢了。可以改变方式,通过另外的线程,完成要做的任务。

1. 线程的回调函数 myfunc

2. 循环运行的线程函数 threadtimer

3. 创建线程,无需等待线程结束

4. 进入主程循环

#include once "glib.bi"'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guintPrint "Main-program time = ", Time$Return TRUE
End Function'Thread endless loop
Function threadtimer(ByVal invalue as Integer) as integerDo while inkey$<> CHR$(27)Sleep 200Print "Thead-process time = ", Time$myfunc(NULL)LoopReturn TRUE
End function'Create thread
Dim as any ptr threadid = threadcreate( CAST(Any Ptr, @threadtimer), 0 )'Main loop
'Press ESC to terminate
Do while inkey$<>chr$(27)Sleep 100
LoopEnd

执行结果:

7e059520ca5749b99fdba50fa189b3a2.png

FreeBasic是多线程的,根据需要还可以创建更多线程,线程循环中sleep 200改为 sleep 100 则线程任务被执行的频率就会更高。

二、让SIGALRM为线程提供安全保护

上面的线程是个死循环,如果主程序很长,任务很重等其它原因死掉了,线程应该自动退出、让出系统资源。让SIGALRM做此事情即可解决这一问题。

系统在正常运行时,SIGALRM应该是长活的,如同C#中的系统线程池,它不是由用户创建的。它可以自动更新共享变量,在线程循环中对变量更新进行判断,如果SIGALRM在更新共享变量,则清FlagSet, 否则自动累加,这样如果因程序死掉了而不能更新共享变量的话,线程应该也就因此自动结束了。

三、可以使用线程锁

如果线程读写变得复杂,可以对变量或过程读写加锁,freebasic 支持 mutexlock 和 mutexunlock。

#include once "glib.bi"const SIGALRM=14
Dim shared as Integer FlagSet = 0
Dim shared as Integer FlagCounterNew = 0
Dim shared as Integer FlagCounterOld = 0Dim shared as any ptr maintlock, threadlock
Dim as any ptr threadidDeclare Function Signal cdecl  alias "signal" (ByVal V_Signal As long, byval V_Function As Any Ptr) as Any Ptr
Declare Function Raise cdecl  alias "raise" (ByVal V_Signal As long) as Any Ptr
Declare function alarm cdecl alias "alarm" (byval __seconds as uinteger) as uintegermainlock = mutexcreate( )
threadlock = mutexcreate( )'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guintPrint "Main-program time = ", Time$Return TRUE
End Function'Thread endless loop
Function threadtimer(ByVal invalue as Integer) as integerDo while inkey$<> CHR$(27)Mutexlock threadlockIf FlagCounterNew <> FlagCounterOld thenFlagSet = 0FlagCounterOld = FlagCounterNewElseFlagSet += 1If FlagSet > 20 thenFlagSet = 0Exit DoEnd ifEnd ifMutexUnlock threadlockSleep 200Print "Thead-process time = ", Time$myfunc(NULL)LoopReturn TRUE
End functionSub timerevent()MutexLock mainlockFlagCounterNew += 1If FlagCounterNew > 1000 thenFlagCounterNew = 0End ifMutexUnlock mainlock
End Subsub wait_alarm(iSigno As Integer)'?"This is the scheduled event SIG = " & Str$(iSigno) & "--- @: " & Time$alarm(1)		'loads another alarm events: each alarm event is a single time event, so to repeat it it must be set again every timetimerevent
end subsignal(SIGALRM, @wait_alarm)		'when SIGALRM triggered, call subroutine wait_alarm
alarm(2)	'Create thread
threadid = threadcreate( CAST(Any Ptr, @threadtimer), 0 )'Main loop
'Press ESC to terminate
Do while inkey$<>chr$(27)Sleep 100
LoopEnd

如果是gtk界面程序,可以简单地使用g_timeout_add(100, @myfunc, NULL) 完成100毫秒间隔的回调函数执行,直到回调函数返回FALSE结束。

#INCLUDE once gtk/gtk.h
#DEFINE __USE_GTK3__

'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guint
     Print "Callback time = ", Time$
    Return TRUE
End Function

gtk_init(NULL, NULL)
g_timeout_add(100, @myfunc, NULL)
gtk_main()

如果还有一个回调任务要完成,则加多一行任务,比如:

g_timeout_add(100, @myfunc1, NULL)

g_timeout_add(100, @myfunc2, NULL)

可直接编译运行的实测代码:

#DEFINE __USE_GTK3__
#Include once "gtk/gtk.bi"Declare Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guint'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guintPrint "Callback time = ", Time$Return TRUE
End Functiongtk_init(NULL, NULL)
var mycall = g_timeout_add (100, @myfunc, NULL)
gtk_main()

上面的代码测试了Timer, 但主程序只能等待gtk_main()结束才能继续。如果将gtk这段代码作为一个线程运行,而且主程序不等待线程结束的话,则线程运行的同时主程序仍然继续运行。

测试代代码改写为:

#DEFINE __USE_GTK3__
#Include once "gtk/gtk.bi"Declare Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guint'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guintPrint "Callback time = ", Time$Return TRUE
End FunctionSub sidethread()gtk_init(NULL, NULL)var mycall = g_timeout_add (300, @myfunc, NULL)gtk_main()
End SubDim as any ptr threadid = threadcreate( CAST(Any Ptr, @sidethread), 0 )''Main loop
Do while inkey$<>chr$(27)Print "Main program time = ", Time$Sleep 100
LoopEnd 0

Gnu 对 glib 描述有一段文字(): Libraries may contain wrappers of some of these functions, e.g. gtk_main(), gtk_main_quit() and gtk_events_pending().

是说gtk_main(), gtk_main_quit,gtk_events_pending() 是 g_main_xxx 的封装 (wrapper) --- (Gnu 站点链接贴图本意只是为了不在CSDN外链)。上面的测试程序引用了 gtk,下面的测试程序使用glib验证了同样的效果。

#Include once "glib.bi"Declare Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guint'Thread callback
Function myfunc Cdecl (Byval NotUsed As Any Ptr) as guintPrint "Callback time = ", Time$Return TRUE
End FunctionDim shared as GMainLoop PTR gml = NULL
Sub sidethread()gml = g_main_loop_new(NULL, FALSE)var mycall = g_timeout_add (300, @myfunc, NULL)g_main_loop_run(gml)g_main_loop_unref(gml)
End SubDim as any ptr threadid = threadcreate( CAST(Any Ptr, @sidethread), 0 )''Main loop
Do while inkey$<>chr$(27)Print "Main program time = ", Time$Sleep 100
Loop'When main program terminate, all thread should be removed off
'but, anyway, g_main_loop_quit(gml) is not harm to added here
g_main_loop_quit(gml)
End 0

在CSDN上又查看了些关于Glib的博客,补了一句:g_main_loop_unref(gml)

学习参考博主李尔阳博文:七、GLib主要的事件循环(The Main Event Loop)_glib 事件源 套接字-CSDN博客

凭籍多线程能力,可以在主程序中实现对其它语言封装的.so界面进行调用。gcc的.so封装和freebasic的.so封装需要一些方法,但试练都不是特别复杂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/268742.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(十)SpringCloud系列——openfeign的高级特性实战内容介绍

前言 本节内容主要介绍一下SpringCloud组件中微服务调用组件openfeign的一些高级特性的用法以及一些常用的开发配置&#xff0c;如openfeign的超时控制配置、openfeign的重试机制配置、openfeign集成高级的http客户端、openfeign的请求与响应压缩功能&#xff0c;以及如何开启…

DevOps学习 | 如何应对IT服务交付中的问题?

目录 前言 DevOps是什么&#xff1f; DevOps发展历程 DevOps与微服务、容器的关系 书本推荐 前言 作为一个热门的概念&#xff0c;DevOps这个名词在程序员社区里频频出现&#xff0c;备受技术大佬们的追捧。甚至网络上有了“南无DevOps”的戏言&#xff08;南无在梵语的意…

LLM@本地大语言模型@Gemma的安装与使用@dockerDesktop的安装和启动

文章目录 准备refsollama安装过程2b模型的效果小结&#x1f47a; ollama的进一步使用帮助文档查看ollama安装了哪些模型使用皮肤来使聊天更易用 使用Chatbot UI皮肤安装docker&#x1f47a;启动docker载入和退出dockerchatbot 网页版皮肤 使用命令行聊天小结&#x1f47a; 准备…

《精益DevOps》:填补IT服务交付的认知差距,实现高效可靠的客户期望满足

写在前面 在当今的商业环境中&#xff0c;IT服务交付已经成为企业成功的关键因素之一。然而&#xff0c;实现高效、可靠、安全且符合客户期望的IT服务交付却是一项艰巨的任务。这要求服务提供商不仅具备先进的技术能力&#xff0c;还需要拥有出色的组织协作、流程管理和态势感…

docker 常用命令大全(基础、镜像、容器、数据卷)

文章目录 1.docker基础命令2.docker镜像命令2.1 镜像名称2.2 镜像命令2.3 案例1--拉取、查看镜像2.4 案例2--保存、导入镜像 3.docker容器命令3.1 容器命令3.2 案例--创建并运行一个容器3.3 案例--进入容器&#xff0c;修改文件3.4 小结 4.数据卷4.1 什么是数据卷4.2 数据卷操作…

打造禹州中医药大模型,以AI驱动业务创新(内附孙思邈GPT内测版)

大禹智库 第78 期&#xff08;总第409 期&#xff09; 2024年 3 月 4 日 在中医药传承与发展的关键时期&#xff0c;结合许昌市的地域特色和产业优势&#xff0c;大禹智库提出“打造禹州中医药大模型&#xff0c;以AI驱动业务创新”的战略构想。本报告围绕构建禹州中医药现代化…

【促销定价】背后的算法技术3-数据挖掘分析

【促销定价】背后的算法技术3-数据挖掘分析 01 整体分析1&#xff09;整体概览2&#xff09;类别型特征概览3&#xff09;数值型特征概览 02 聚合分析1&#xff09;天维度2&#xff09;品维度3&#xff09;价格维度4&#xff09;数量维度 03 相关分析1&#xff09;1级品类2&…

C++学习笔记:set和map

set和map set什么是setset的使用 关联式容器键值对 map什么是mapmap的使用map的插入方式常用功能map[] 的灵活使用 set 什么是set set是STL中一个底层为二叉搜索树来实现的容器 若要使用set需要包含头文件 #include<set>set中的元素具有唯一性(因此可以用set去重)若用…

Docker之数据卷自定义镜像

文章目录 前言一、数据卷二、自定义镜像 前言 Docker提供了一个持久化存储数据的机制&#xff0c;与容器生命周期分离&#xff0c;从而带来一系列好处&#xff1a; 总的来说Docker 数据卷提供了一种灵活、持久、可共享的存储机制&#xff0c;使得容器化应用在数据管理方面更加…

Newtonsoft.Json

目录 引言 1、简单使用 1.1、官方案例 1.2、JsonConvert 2、特性 2.1、默认模式[JsonObject(MemberSerialization.OptIn/OptOut)] 2.2、序列化为集合JsonArrayAttribute/JsonDictionaryAttribute 2.3、序列化该元素JsonProperty 2.4、忽略元素JsonIgnoreAttribute 2.5、…

超全Chat GPT论文修改指令

文献综述指令润色修改指令论文选题指令论文大指令研究理论指令论文致谢指令参考文献指令论文润色整体逻辑论文整体优化提问指令 1&#xff0e;文献综述指令 请你帮我写一份关于&#xff08;研究主题&#xff09;的文献综述。我的论文选题方向是 XXXX &#xff0c;我已经找到了…

WordPress上传图片错误:不是合法的JSON响应

最近在进行WordPress迁移至新服务器的过程中&#xff0c;遭遇到一个棘手的问题&#xff0c;即在编辑文章并上传图片时&#xff0c;不断遭遇“此响应不是合法的JSON响应”的错误。经过多次验证和搜索&#xff0c;最终确定问题的根本原因并不在于禁用 Gutenberg 编辑器或安装经典…

uniapp从入门到精通(全网保姆式教程)~ 别再说你不会开发小程序了

目录 一、介绍 二、环境搭建&#xff08;hello world&#xff09; 2.1 下载HBuilderX 2.2 下载微信开发者工具 2.3 创建uniapp项目 2.4 在浏览器运行 2.5 在微信开发者工具运行 2.6 在手机上运行 三、项目基本目录结构 四、开发规范概述 五、全局配置文件&#xff0…

如何在Node.js中使用定时器

在Node.js中使用定时器是一项常见且重要的任务&#xff0c;特别是在需要执行定时任务或者轮询操作的情况下。Node.js提供了多种方式来实现定时器功能&#xff0c;包括setTimeout、setInterval和setImmediate等方法。本篇博客将介绍如何在Node.js中使用这些定时器&#xff0c;并…

Kubernetes的Sevice管理

服务原理: 所有服务都是根据这个服务衍生或者变化出来,根服务---- 服务感知后端靠标签 slelector 标签选择器 kubectl label pods web1 appweb kubectl cluter-info dump | grep -i service-cluster-ip-range 服务ip取值范围 Service 管理: 创建服务: --- kind: Serv…

python复盘(1)

1、变量名的命名规则 #3、变量名的命名规则&#xff1a;可以用中文作为变量名&#xff1b;其他和go语言一样 # 变量名可以用数字、字母、下划线组成&#xff0c;但是数字不能作为开头 # 变量名不能使用空格&#xff0c;不能使用函数名或关键字 # 变量名最好能表示出他的作用2、…

大模型(LLM)的量化技术Quantization原理学习

在自然语言处理领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;在自然语言处理领域的应用越来越广泛。然而&#xff0c;随着模型规模的增大&#xff0c;计算和存储资源的需求也急剧增加。为了降低计算和存储开销&#xff0c;同时保持模型的性能&#xff0c;LLM大模型…

OpenGL 实现色温、色调、亮度、对比度、饱和度、高光

1.简介 色温&#xff1a;简单理解是色彩的温度&#xff0c;越低越冷如蓝色&#xff0c;约高越暖如红色。 亮度&#xff1a;增加就是给图片所有色彩加白色&#xff0c;减少加黑色。注意是只加黑白两种颜色&#xff0c;不然容易跟纯度弄混。 对比度&#xff1a;增加就是让白的…

2023人机交互期末复习

考试题型及分值分布 1、选择题&#xff08;10题、20分&#xff09; 2、填空题&#xff08;10题、20分&#xff09; 3、判断题&#xff08;可选、5题、10分&#xff09; 4、解答题&#xff08;5~6题、30分&#xff09; 5、分析计算题&#xff08;1~2题、20分&#xff09; 注意&…

如何做代币分析:以 LEO 币为例

作者&#xff1a; lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a;LEO 代币仪表板 &#xff08;仅包括以太坊数据&#xff09; 在加密货币和数字资产领域&#xff0c;代币分析起着至关重要的作用。代币分析指的是深入研究与代币相关的数…