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

Vala编程语言高级特性-多线程

多线程


Vala 中的线程

        使用 Vala 编写的程序可以拥有多个执行线程,使其能够同时执行多个任务。具体如何管理这些线程超出了 Vala 的范围——线程可能共享也可能不共享单个处理器核心,这取决于运行环境。

一个非常简化的示例:


void thread_func() {stdout.printf("child_thread is running.\n");
}void main() {if (!Thread.supported()) {error("Cannot run without thread support.\n");}var thread = new Thread<void> ("child_thread", thread_func);stdout.printf("main_thread is running");
}

注意

请注意 main 方法开头的测试。

最初,UNIX 没有线程,这意味着一些传统的 UNIX API 在线程程序中可能存在兼容性问题。

使用此测试可以检查当前环境是否支持线程。

在大多数情况下,可以省略此测试。

现在看下面的语句:

var thread = new Thread<void> ("new_thread", thread_func);

        我们创建了一个新线程,并且它会立即启动。第一个参数是线程的名称,第二个参数是新线程要执行的内容(函数)。泛型参数是线程返回值的类型。

        这个程序仍然不会按我们预期的那样运行,因为如果没有任何形式的事件循环,当 Vala 程序的主/根/父线程(为运行 "main" 而创建的线程)结束时,程序就会终止。为了控制这种行为,你可以让线程进行协作。使用事件循环和异步队列可以非常强大地实现这一点,但在这篇线程介绍中,我们只展示线程的基本功能。

        如果其主/父线程执行完毕,子线程将被杀死。根据这个事实,我们应该告诉主线程等待子线程完成,这是通过调用 Thread 模块中的 join 方法来实现的。

// ......
var thread = new Thread<void> ("child_thread", thread_func);
stdout.printf("main_thread is running");
thread.join();   // 注意

        因为 join 方法,主线程必须等待子线程完成。

        此外,线程可以告诉系统它当前不需要执行,从而建议应该改为运行另一个线程,这是通过静态方法 Thread.yield() 来完成的。如果将此语句放在上述 main 方法的末尾,运行时系统将暂停主线程片刻,并检查是否有其他可以运行的线程——当发现新创建的线程处于可运行状态时,它将转而运行该线程直到其完成——这样程序的行为看起来就符合预期了。然而,这并不能保证一定会发生。系统能够决定线程何时运行,因此可能在新线程完成之前就重新启动主线程并结束了程序。

        所有这些示例都有一个潜在的问题,即新创建的线程不知道它应该在什么上下文中运行。在 C 语言中,你需要向线程创建方法提供一些数据,而在 Vala 中,你通常会传递一个实例方法,而不是静态方法。

        更多示例请参见线程示例。

资源控制

        每当多个执行线程同时运行时,就有可能发生数据被同时访问的情况。这可能导致竞态条件,即结果取决于系统决定在线程之间切换的时机。

        为了控制这种情况,你可以使用 lock 关键字来确保某些代码块不会被其他需要访问相同数据的线程中断。最好的展示方式可能是通过一个示例:


public class Test : GLib.Object {private int a { get; set; }public void action_1() {lock (a) {int tmp = a;tmp++;a = tmp;}}public void action_2() {lock (a) {int tmp = a;tmp--;a = tmp;}}
}

        这个类定义了两个方法,这两个方法都需要更改 "a" 的值。如果这里没有 lock 语句,这些方法中的指令可能会交织执行,导致对 "a" 的更改结果实际上是随机的。由于这里有 lock 语句,Vala 将保证如果一个线程已经锁定了 "a",另一个需要相同锁的线程将必须等待。

        在 Vala 中,只能锁定正在执行代码的对象所属的成员。这看起来像是一个主要的限制,但实际上,这种技术的标准用法应该涉及那些各自负责控制一个资源的类,因此所有的锁定确实都是在类内部进行的。同样,在上面的示例中,对 "a" 的所有访问都被封装在类中。

http://www.dtcms.com/a/423546.html

相关文章:

  • 上海网站建设培训学校廊坊做网站优化的公司
  • 在JavaScript / HTML中,动态计算调整文字大小
  • Video over HTTPS,视频流(HLSDASH)在 HTTPS 下的调试与抓包实战
  • 黄页88网站关键词怎么做农村自建房100张图片
  • 网站开发经验总结与教训徐州开发的网站
  • 重庆福彩建站北京提供24小时医疗服务
  • 浅谈文件上传
  • react 初体验2
  • 内网穿透的原理和配置
  • 科技护航童心:物联网助力科学护眼与智能哄娃新方式
  • 挂网站需要什么服务器wordpress 短信验证码
  • 【代码随想录day 29】 力扣 135.分发糖果
  • 上海企业建站咨询c 微信小程序开发教程
  • 新奇特:数字永生,当神经网络成为你的数字化身
  • 开题报告之基于SpringAI的AI笔记智能体的设计与实现
  • 【SpringBoot】@Scheduled是静态配置,是我想改时间,但又不想引入其他组件,还有什么方案么?
  • ip做网站地址电商平面设计师
  • C语言内存布局:虚拟地址空间详解
  • 南昌比较好的网站设计白银市建设网站
  • Redis:高性能内存数据库的六大核心优势
  • Qt 程序包括Qt Creator 无法使用fcitx 输入法的解决办法
  • 【题解】洛谷 P4051 [JSOI2007] 字符加密 [后缀数组]
  • 免费 网站建设火车头 wordpress接口
  • 【MYSQL 】SQL 行列转换实战:如何用 CASE WHEN 与 SUM/MAX 重塑部门表
  • 网站申请支付宝支付网站关键词选取的方法
  • 最新版谷歌浏览器Axure插件(免翻墙)
  • 网站加载特效代码开源镜像网站开发
  • 虚拟串口工具vspd
  • 从入门到精通【Redis】理解Redis事务
  • Android16 wifi启动后自动连接的第一个wifi分析和修改