如何解决任务间异步数据交换
“Toit 中的任务”部分中的文档表明该语言具有用于在任务之间进行异步数据交换的设施。如果我理解正确,那么监视器包中的两个类:Channel 和 MailBox 提供了这个机会。不幸的是,我没有找到使用这些类的例子,所以我请你至少给出两个任务实现的最简单的例子:
- 其中一个任务是消息生成器,例如,它发送 第二个任务的整数或字符串。第二个任务得到这些 数字或字符串。也许在这种情况下,Channel 类应该 使用。
- 这两个任务中的每一个都是消息的生成器和接收器。 那些。第一个任务向第二个任务发送消息,然后 异步接收第二个任务生成的消息。 从描述来看,MailBox 类应该用于 这种情况。
提前致谢, 马克
解决方法
感谢您的提问。
这是第一部分的示例,使用 Channel。如果您有另一个任务的消息流,这个类很有用。
import monitor
main:
// A channel with a backlog of 5 items. Once the reader is 5 items behind,the
// writer will block when trying to send. This helps avoid unbounded memory
// use by the in-flight messages if messages are being generated faster than
// they are being consumed. Decreasing this will tend to reduce throughput,// increasing it will increase memory use.
channel := monitor.Channel 5
task:: message_generating_task channel
task:: message_receiving_task channel
/// Normally this could be looking at IO ports,GPIO pins,or perhaps a socket
/// connection. It could block for some unknown time while doing this. In this
/// case we just sleep a little to illustrate that the data arrives at random
/// times.
generate_message:
milliseconds := random 1000
sleep --ms=milliseconds
// The message is just a string,but could be any object.
return "Message creation took $(milliseconds)ms"
message_generating_task channel/monitor.Channel:
10.repeat:
message := generate_message
channel.send message
channel.send null // We are done.
/// Normally this could be looking at IO ports,or perhaps a socket
/// connection. It could block for some unknown time while doing this. In this
/// case we just sleep a little to illustrate that the data takes a random
/// amount of time to process.
process_message message:
milliseconds := random 1000
sleep --ms=milliseconds
print message
message_receiving_task channel/monitor.Channel:
while message := channel.receive:
process_message message
这是使用邮箱的示例。如果您有一个任务处理请求并响应其他任务,这个类很有用。
import monitor
main:
mailbox := monitor.Mailbox
task:: client_task 1 mailbox
task:: client_task 2 mailbox
task --background:: factorization_task mailbox
/// Normally this could be looking at IO ports,or perhaps a socket
/// connection. It could block for some unknown time while doing this. For
/// this example we just sleep a little to illustrate that the data arrives at
/// random times.
generate_huge_number:
milliseconds := random 1000
sleep --ms=milliseconds
return (random 100) + 1 // Not actually so huge.
client_task task_number mailbox/monitor.Mailbox:
10.repeat:
huge := generate_huge_number
factor := mailbox.send huge // Send number,wait for result.
other_factor := huge / factor
print "task $task_number: $factor * $other_factor == $huge"
// Factorize a number using the quantum computing port.
factorize_number number:
// TODO: Use actual quantum computing instead of brute-force search.
for i := number.sqrt.round; i > 1; i--:
factor := number / i
if factor * i == number:
return factor
// This will yield so the other tasks can run. In a real application it
// would be waiting on an IO pin connected to the quantum computing unit.
sleep --ms=1
return 1 // 1 is sort-of a factor of all integers.
factorization_task mailbox/monitor.Mailbox:
// Because this task was started as a background task (see 'main' function),// the program does not wait for it to exit so this loop does not need a real
// exit condition.
while number := mailbox.receive:
result := factorize_number number
mailbox.reply result
,
我很确定邮箱示例在 3 月底运行良好。我决定现在检查它并得到错误:
-
如果是控制台 Toit:
./web.toit:8:3: 错误:参数不匹配:'task' 任务 --background:: factorization_task 邮箱 ^~~~ 编译失败。
-
如果是终端:
micrcx@micrcx-desktop:~/toit_apps/Hsm/communication$ toit 执行mailbox_sample.toit 邮箱样本.toit:8:3:错误:参数不匹配:“任务” 任务 --background:: factorization_task 邮箱 ^~~~ 编译失败。
-
这可能是由于最新的 SDK 更新造成的。以防万一:
Toit CLI: | v1.0.0 | 2021-03-29 |
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。