如何创建线程序列以按启动顺序执行任务?

时间:2018-10-22 03:17:45

标签: c++ multithreading

我不是计算机科学背景的人。请为我指出以下内容的正确资源。这是我使用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执行时间很长(不确定,因为这涉及硬件驱动程序),那么会有多个线程在等待资源。我不知道任务是否按启动顺序执行。我认为操作系统要根据其规则执行这些操作。因此,我需要一种使这些线程按启动顺序执行的方法或方法。

非常感谢。

2 个答案:

答案 0 :(得分:0)

我的主张:您可以将链接列表与互斥锁或队列一起使用。

  1. 链接列表(或向量?对不起,我习惯了server error: request: GET /ws/users/signup/312c9eaf-f27b-43c7-8dac-445a628c3be8, exception: bucket_id is not a column defined in this metadata):

    • 在第一个循环中,执行一些生成“数组”的工作,并在列表末尾添加新的整数。
    • 处理这些整数的过程(线程)从列表的开头拉出元素
  2. 队列: 好吧,队列的操作大致与上述相同,但是您选择的队列库已经完成了很多处理

答案 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