aardio多任务开发多线程线程池

职场菊菊子 2024-04-30 20:32:14

aardio作为一门发展了17年的国产编程语言,自然具有通过多线程并行执行任务的能力。今天一起看看aardio如何执行多线程。

什么是线程

要了解什么是线程,需要先了解什么是进程。进程是一个应用程序运行的最小单位。一个应用程序的进程在运行的时候,至少包括一个线程,通常称之为主线程,比如我们的窗体界面线程,一般就是主线程。一个应用程序除了主进程之外,可能会创建新的线程去执行一些执行起来比较慢的操作。应用程序此时就有了多个线程。

为什么用多线程

根据上面的介绍,使用多线程的目的很明确,提升应用程序处理多任务的并行能力,优化程序性能,让程序运行更流畅更迅速。对于windows窗体程序而言,可以在处理复杂多任务的同时,窗体主界面不卡顿。

创建单个线程

aardio提供了几种创建线程的方式。

thread.invoke(线程函数,其他参数)

创建线程但不返回线程句柄,线程句柄已自动关闭。注意线程函数有独立的全局变量环境,线程引用的库应当在线程函数内单独导入。创建后线程会自动运行。

import win.ui;/*DSG{{*/var winform = win.form(text="多线程 —— 入门";right=536;bottom=325)winform.add(button={cls="button";text="启动线程";left=27;top=243;right=279;bottom=305;db=1;dl=1;dr=1;font=LOGFONT(h=-16);z=1};edit={cls="edit";left=27;top=20;right=503;bottom=223;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=2})/*}}*/winform.button.oncommand = function(id,event){ //禁用按钮并显示动画 winform.button.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"} //创建工作线程 thread.invoke( //线程启动函数 function(winform){ for(i=1;3;1){ sleep(1000); //在界面线程执行 sleep 会卡住 //调用界面控件的成员函数 - 会转发到界面线程执行 winform.edit.print("工作线程正在执行,时间:" + tostring( time() ) ); } winform.button.disabledText = null; },winform //窗口对象可作为参数传入工作线程 )}

thread.invokeAndWait(线程函数,其他参数)

调用并等待线程函数执行完毕,然后获取此线程函数的返回值。在界面线程等待时界面仍可响应用户操作,线程函数的返回值会返回给调用线程。线程函数拥有独立的全局变量,并应遵守多线程调用规则。值得注意的是,前面介绍的thread.invoke不会返回执行结果。

参数@1指定的线程函数,

参数@1之后的其他可选参数会作为调用线程函数的参数。

import win.ui;/*DSG{{*/var winform = win.form(text="aardio form";right=759;bottom=469)winform.add(button={cls="button";text="读取网页";left=272;top=368;right=624;bottom=440;z=1};edit={cls="edit";text="edit";left=48;top=40;right=720;bottom=336;edge=1;multiline=1;z=2})/*}}*/winform.button.oncommand = function(id,event){ winform.button.disabledText = {"✶";"✸";"✹";"✺";"✹";"✷"} winform.edit.text = thread.invokeAndWait( function(winform){ sleep(3000);//暂停模拟一个耗时的操作 import inet.http; return inet.http().get("http://www.aardio.com"); },winform ) winform.button.disabledText = null;}winform.show()win.loopMessage();线程池

给给个任务创建一个线程,看起来没什么问题。但是,当任务数量很多时,比如成百上千个,创建这么多线程对于操作系统而言会造成很大开销,频繁在多线程切换反而会降低线程执行的性能。这时候,我们就需要创建线程池,管理多线程。

aardio给我们提供了两种线程池方案,thread.works执行相同任务(相同的函数)和thread.manage执行不同任务(不同的函数)。两者都可以指定线程池大小,新添加的任务从线程池里面取线程执行任务。

分别看看案例。thread.manage案例:

import console;import thread.manage;//创建线程管理器manage = thread.manage(3);var thrdFunc = function(name){ import win; import console; for(i=1;10;1){ console.log( thread.getId(),name ) if( !win.delay(1000) ){ //主线程可以用 manage.quitMessage()中断这个循环 console.log("收到退出指令") return; } } return 67;}//创建线程,如果线程池已满会自动等待其他线程结束manage.create(thrdFunc,"线程1").onEnd = function(...){ console.log("线程1的回调",...);} //创建线程(忽略线程返回值),如果线程池已满会自动等待其他线程结束manage.createLite(thrdFunc,"线程2").onEnd = function(){ console.log("线程2的回调");}manage.create(thrdFunc,"线程3");/*创建所有线程以后,必须调用 manage.waitClose() 函数等待所有线程执行完成,manage.waitClose() 也会负责触发 onEnd 回调,并自动关闭已结束线程的线程句柄。*/manage.waitClose(); console.pause();

thread.works案例

import console;import thread.works;import time;var testWorksSameTask = function(){ var works = thread.works( 4, function(...) { import console; thread.lock("写控制台") console.log("线程ID" + thread.getId(),",开始工作,接收到任务指令参数",...) thread.unlock("写控制台") return "返回值,线程ID" + thread.getId(); } ); //分派任务 for(i=1;10;1){ works.push("task ->" + i) } //退出程序前,等待任务完成并关闭所有线程 works.waitClose( function(r){ console.log( "检查成果", r ) } )}testWorksSameTask()execute("pause")
0 阅读:2

职场菊菊子

简介:感谢大家的关注