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.mzph.cn/news/724044.shtml

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

相关文章

Python读取influxDB数据库

1. influxDB连接 首先用InfluxDBStudio软件连接influxDB数据库来查看所有表&#xff1a; 2. 写sql语句来查询数据 然后和平时写sql查询语句一样&#xff0c;先创建连接client&#xff0c;然后调用其query函数来查询获取数据 self.client influxdb.InfluxDBClient(hostinflu…

抖店怎么做起来?2024新版操作逻辑,做项目要做一米宽万米深

我是王路飞。 不知不觉间&#xff0c;我已经在抖音电商这条赛道深耕走过了四年。 这四年里&#xff0c;我们有了自己的黑标品牌旗舰&#xff0c;有了自己的仓库配套周边&#xff0c;有了自己的模式体系人员&#xff0c;有了数不清的类目和产品操作经验。 收获着身后团队伙伴…

PXE网络启动实战(第二篇 使用WDS启动WIN10PE)

目录 一、PE光盘结构分析 二、WIM格式的部署 三、安装配置Windows部署服务 1.准备虚拟机 2.复制WinPE的ISO文件到服务器 3.将Win10PE的WIM释放出来 4.配置服务器,设置固定IP地址 5.安装DHCP、DNS服务

EdgeX Foundry - 连接 MQTT 设备

文章目录 一、概述1.安装说明2.MQTT 设备模拟器2.1.模拟器设计2.2.Spring Boot 程序源码2.2.1.MQTT2.2.2.JsonUtils2.2.3.Device 2.3.程序配置 二、连接 MQTT 设备1.docker-comepse2.设备配置文件3.启动 EdgeX Foundry4.访问 UI4.1. consul4.2. EdgeX Console 5.创建 MQTT 设备…

由数据范围反推算法复杂度以及算法内容

一般ACM或者笔试题的时间限制是1秒或2秒。 在这种情况下&#xff0c;C代码中的操作次数控制在 1 0 7 ∼ 1 0 8 10^7\sim10^8 107∼108为最佳。 下面给出在不同数据范围下&#xff0c;代码的时间复杂度和算法该如何选择&#xff1a; n ≤ 30 n\leq30 n≤30&#xff0c;指数级别…

2024年字节跳动+京东+美团面试总结,程序员经验分享

现在的IT行业竞争压力越来越大&#xff0c;尤其是Android开发行业。而很多Android程序员却每天都在重复CRUD,原地徘徊&#xff01; 今年年初&#xff0c;你就想改变现状&#xff0c;于是在网上刷了大量面试题&#xff0c;强行记下之后&#xff0c;开始参加面试&#xff01;但是…

微信小程序开发系列(七)·如何实现小程序页面的快速跳转、小程序样式·尺寸单位rpx以及全局样式和局部样式的区别

微信小程序开发_时光の尘的博客-CSDN博客 目录 1. 小程序样式和组件介绍 2. 如何实现页面的快速跳转 3. 小程序样式尺寸单位rpx 3.1 使用px 3.2 使用rpx 4. 全局样式和局部样式 4.1 全局样式 4.2 局部样式 1. 小程序样式和组件介绍 在开发 Web网站的时候&am…

C语言深入学习 --- 2.指针的进阶

文章目录 第二章指针的进阶1.字符指针2.指针数组3.数组指针3.1数组指针的定义3.2 &数组名与数组名的区别3.3 数组指针的使用 4.数组参数与指针参数4.1 一维数组的传参4.2 二维数组的传参4.3 一级指针传参4.4 二级指针传参 5.函数指针6.函数指针数组7.指向函数指针数组的指针…

15 实战:Kaggle房价预测 + 课程竞赛:加州2020年房价预测【李沐动手学深度学习课程笔记】

15 实战&#xff1a;Kaggle房价预测 课程竞赛&#xff1a;加州2020年房价预测【李沐动手学深度学习课程笔记】https://zhuanlan.zhihu.com/p/685343754 写在前面&#xff1a;这里格式很乱&#xff0c;代码直接去知乎copy 1 实战Kaggle比赛&#xff1a;预测房价 1.1 实现几个函…

【系统安全加固】Centos 设置禁用密码并打开密钥登录

文章目录 一&#xff0c;概述二&#xff0c;操作步骤1. 服务器端生成密钥2. 在服务器上安装公钥3.下载私钥到本地&#xff08;重要&#xff0c;否则后面无法登录&#xff09;4. 修改配置文件&#xff0c;禁用密码并打开密钥登录5. 重启sshd服务6. 配置xshell使用密钥登录 一&am…

线段树及例题动态求连续区间和 Java代码

线段树 作用 1、单点修改 2、区间查询 相比于树状数组&#xff0c;线段树代码更复杂但应用更广泛 例题 Acwing 1264. 动态求连续区间和 给定 n n n 个数组成的一个数列&#xff0c;规定有两种操作&#xff0c;一是修改某个元素&#xff0c;二是求子数列 [ a , b ] [a,b] […

leetcode 200 . 岛屿数量

链接 : . - 力扣&#xff08;LeetCode&#xff09; 广搜 : BFS 适合于解决两个点之间的最短路问题 &#xff1b; 以起始点为中心一圈一圈的进行搜索 , 一旦遇到终点 &#xff0c; 记录之前走过的结点就是一条最短路 &#xff1b; 代码模板 : int dir[4][2] {0, 1, 1,…

自动化测试基础——Pytest框架之YAML详解以及Parametrize数据驱动

文章目录 一、YAML详解1.YAML作用2.YAML语法结构3.YAML数据类型3.1.对象3.2.数组3.3.标量 4.YAML的引用5.YAML类型转换 二、YAML的读写与清空1.YAML的读2.YAML的写3.YAML的清空 三、pytest的parametrize简单数据驱动四、pytest的parametrize结合yaml实现数据驱动五、解决pytest…

FreeRTOS操作系统学习——空闲任务及其钩子函数

空闲任务 当 FreeRTOS 的调度器启动以后就会自动的创建一个空闲任务&#xff0c;这样就可以确保至少有一任务可以运行。但是这个空闲任务使用最低优先级&#xff0c;如果应用中有其他高优先级任务处于就绪态的话这个空闲任务就不会跟高优先级的任务抢占 CPU 资源。空闲任务还有…

FlinkSQL ChangeLog

01 Changelog相关优化规则 0101 运行upsert-kafka作业 登录sql-client&#xff0c;创建一个upsert-kafka的sql作业&#xff08;注意&#xff0c;这里发送给kafka的消息必须带key&#xff0c;普通只有value的消息无法解析&#xff0c;这里的key即是主键的值&#xff09; CREA…

EC600模块通过AT指令接入阿里云物联网平台并发布属性

摘要&#xff1a;本文介绍一下如何通过EC600模块的AT指令&#xff0c;将设备属性值发送到阿里云物联网平台的方法。 这个模块供电可以是 5-16V 和电脑通过USB串口连接&#xff0c;4线即可。未来集成到自己的系统中的时候&#xff0c;可以直接发送指令即可。 使用的软件是FreeAT…

【Vue3】Hooks:一种全新的组件逻辑组织方式

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

STM32作为SPI slave与主机异步通信

背景 最近被测试提了个BUG&#xff0c;说某款产品在用户按下前面板的按键后&#xff0c;对应的按键灯没有亮起来。前面板跟主机是通过SPI口通信&#xff0c;前面板是从机&#xff0c;从机想要主动发送消息&#xff0c;需要通过GPIO中断来通知主机&#xff1a; 上图前面板是ST…

阿里云不杀熟,云服务器优惠价格99元一年,新老用户均可购买

2024阿里云服务器优惠活动政策整理&#xff0c;阿里云99计划ECS云服务器2核2G3M带宽99元一年、2核4G5M优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M服务器61元一年、2核4G4M带宽165元1年&#xff0c;云服务器4核16G10M带宽26元1个月、149元半年&#xff0c;云服务器8核…

14 程序地址空间

背景 kernel 2.6.32 32位平台 空间布局图 如何理解地址划分 地址划分&#xff0c;本质是调整地址空间的定义start和end&#xff0c;内存中定义了管理每个区域范围的结构体&#xff0c;叫mm_struct&#xff0c;每个进程都有一个这个结构体指针变量 验证上面划分的结构&#…