我不是计算机科学背景的人。请为我指出以下内容的正确资源。这是我使用Windows窗体在C ++ / CLI中所做的事情。
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e)
{
for (i=0; i < n ;i++){
array<UInt32>^ Buffer = gcnew array<UInt32>(numericTextBox2->IntValue);
/* Some time consuming process. Takes approximately 8 to 10 seconds
and fills Buffer.*/
Thread^ executerThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &Form1::Task));
executerThread.Start((Object^)Buffer)
}
}
private: void Task(Object^ i)
{
array<UInt32>^ Buffer = (array<UInt32>^)i;
mut->WaitOne();
/* Here I send the Buffer as a stream of integers through the hardware driver.
This stream is sent out by the hardware(with built in internal clock) at
a fixed frequency of one integer every micro second. */
mut->ReleaseMutex();
return
}
我需要所有线程按启动顺序运行Task()函数,就像在循环内调用Task()函数一样。我认为如果我的缓冲区很小,将会遇到同步问题。如果我的数组很大,并且准备它们所需的时间大于执行Task的时间,那么程序将达到我的目的,因为线程按调用顺序执行Task()。在这种情况下,最多有两个线程(一个正在运行过程,另一个正在等待资源)。但是,如果我的数组很短并且Task执行时间很长(不确定,因为这涉及硬件驱动程序),那么会有多个线程在等待资源。我不知道任务是否按启动顺序执行。我认为操作系统要根据其规则执行这些操作。因此,我需要一种使这些线程按启动顺序执行的方法或方法。
非常感谢。
答案 0 :(得分:0)
我的主张:您可以将链接列表与互斥锁或队列一起使用。
链接列表(或向量?对不起,我习惯了server error: request: GET /ws/users/signup/312c9eaf-f27b-43c7-8dac-445a628c3be8, exception: bucket_id is not a column defined in this metadata
):
队列: 好吧,队列的操作大致与上述相同,但是您选择的队列库已经完成了很多处理
答案 1 :(得分:0)
我认为解决此问题的最简单方法是排队购买期货。在UI端,启动一个异步任务以填充每个缓冲区。然后,启动最终的异步任务以等待结果并将其传递给驱动程序。类似于以下内容:
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e)
{
std::queue<std::future<std::vector<uint32_t>>> items;
for (i=0; i < n ;i++){
items.push(std::async(std::launch::async, [i] { return CreateBuffer(i); });
}
complete_ = std::async(
std::launch::async,
[items_ = std::move(items)]
{
while (!items_.empty())
{
SendBufferToDriver(items_.front().get());
items_.pop();
}
});
}
这将并行处理所有数组,然后按顺序将它们发送给驱动程序。由于所有操作都是异步完成的,因此还可以避免在处理过程中阻塞UI线程。
并发症:
请记住,这只是一个草图。如果用户在将所有数据发送到驱动程序之前关闭窗口,则还必须考虑如何取消/终止此过程。如果这是一个持续的过程,用户可以多次单击该按钮以随时间添加更多数据,则解决方案会稍微复杂一些。基本思想是相同的,但是您可能希望使用bounded buffer
而不是简单的队列,并且必须移出函数范围。
没有std :: future吗?
如果您被困在没有C ++ 11支持的较旧的编译器上,则可以使用System.Threading.Tasks.Task<T>
完成相同的操作。该界面类似于std::async
/ std::future
。