multithreading - Powershell 同步哈希表线程安全
问题描述
我最近有一个 WPF 脚本遇到问题。
该脚本使用 PSParallel 模块进行子网扫描。当子网 CIDR 小于 21 时,它开始出现问题。
问题是:我有一个并发队列作为同步哈希表的成员。队列用于生产者/消费者模型。扫描线程保持数据入队,GUI线程保持数据出队并将其写入富文本框。出队过程由调度计时器事件处理程序处理,该事件处理程序每 20 毫秒执行一次。当 CIDR >=21 时,没有问题。但是当 CIDR <21 时,有时会抛出错误信息:
Collection was modified; enumeration operation may not execute.
At E:\PSScanner\PSScanner.ps1:446 char:8
+ if($syncHash.Q.Count -ne 0){
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException
我认为同步哈希表是线程安全的,并发队列也是线程安全的。不知道为什么会这样。
解决方案
我最终解决了这个问题。
我正在调用存储在同步哈希表中的脚本块:$syncHash.Output,它将输出字符串发送到并发队列。该脚本块导致输出混乱,工作线程意外终止。直接将数据入队后,而不是调用脚本块,问题解决了。
另外,我有一个 IP 计数器 $syncHash.Count。我认为它应该是线程安全的,因为它存储在同步哈希表中,但实际上并非如此。我每次都得到不准确的计数。设置互斥锁来保护计数器变量后,它可以完美运行。我在想的唯一原因是计数器在 PSParallel 实例(Invoke-Parallel cmdlet)的工作线程中更新。不确定它如何处理哈希表。
谢谢大家的帮助。
推荐阅读
- apache-kafka - 如何将 Suricata 日志发送到 Kafka?
- tensorflow - 如何从 Mobilenet v3 的 cpkt、.meta、.index 和 .pb 文件中加载模型?
- apache-kafka - 在 Kafka 中,我们如何获取主题的元数据?
- python - 在python中搜索未排序的元素列表
- assembly - 在 x86 实模式程序集中编写中断处理程序
- javascript - 从列中获取日期列表并将其格式化为 MM/dd/yyyy
- ruby - 如何迭代嵌套的 Ruby 哈希以基于现有的键/值数据添加新的键/值对?
- python - Python pandas 从嵌入在 web txt 文件中的 csv 创建 datafrane
- laravel - 使用模态 Laravel 的编辑功能问题
- python - 来自不同类的烧瓶重定向