【问题标题】:C++ pthreads multi-tasking [windows]C++ pthreads 多任务处理 [windows]
【发布时间】:2011-05-04 18:20:01
【问题描述】:


对于早期问题的解决方案,有人向我指出多线程(通过 pthreads)。

原来的问题是这样的:
我有两个功能,一个是主体,是实时的;另一个是一个持续运行的阻塞函数。实时,当试图运行阻塞功能时,明显的阻塞,使其对用户无响应,作为实时进程是不可接受的。

最初的目的是让阻塞函数独立于实时解决方案(或至少是伪独立的),我尝试使用 pthreads。

这是代码的简化版本:

void * RenderImages(void * Data)
{
    while(1); //Simulating a permanently blocking process
    return NULL;
}

int main(int ArgC, char *ArgVar[])
{
    pthread_t threads[PTHREAD_NUMBER];


    void *Ptr = NULL;

    int I = 0;
    I = pthread_create(&threads[0], NULL, RenderImages, Ptr);
    if(I != 0)
    {
        printf("pthread_create Error!\n");
        return -1;
    }

    I = pthread_join(threads[0],NULL);

    //Doesn't reach here as pthread_join is blocking

    printf("Testing!\n");
    return 0;
}

然而,上面的代码阻止了调用 pthread_join(这使得 pthread 只不过是直接调用函数的一种不必要的复杂方式 - 这与这一点相悖)。

我的问题是:

我必须使用哪些函数才能使其运行 pthread 几毫秒,暂停进程,然后运行另一个函数,然后返回并运行进程几毫秒等?

如果以上都不可行,有什么办法可以解决原来的问题?

【问题讨论】:

  • 它阻塞是因为你的线程都不做任何事情。这个想法是两者都将同时运行,都做有用的工作。因为它代表你的主线程在加入时阻塞,但另一个线程实际上正在运行。你现在需要在主线程中做一些真正的工作(比如某种循环),在加入之前。
  • 它会起作用(但是,为了简化代码,无限循环实际上会模拟函数调用)。因为它正在调用一个已经定义的类函数,该函数会在它运行的整个持续时间内阻塞。从某种意义上说,我想要的是处理器在运行一个进程、挂起它、运行另一个、挂起该进程,然后运行原始进程方面已经做的事情。
  • @SightS2 这正是线程的作用!我真的没有看到你的问题。操作系统当前正在你的线程之间交换,直到主线程在加入时阻塞,此时只有第二个线程处于活动状态,但你看不到它,因为它们什么都不做!
  • @unapersson 我不完全确定你的意思。如何在线程之间交换?我对 pthreads 完全不熟悉。
  • @SightS2 你不会在线程之间交换——操作系统会为你做这件事,就像它会在 Linux 上的进程之间交换一样。修改您的代码,使 RenderImages 在无限循环中打印“A”,而主函数在无限循环中(连接之前)打印“B”以查看此内容。

标签: c++ windows pthreads


【解决方案1】:

假设“主”线程只关心“阻塞”线程完成工作时,我认为您需要条件变量。查看pthread_cond_waitpthread_cond_signal

【讨论】:

    【解决方案2】:

    pthread_join 是用于等待线程结束的函数。

    http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

    使用 pthread_sigmask 管理挂起状态:

    http://man.yolinux.com/cgi-bin/man2html?cgi_command=pthread_sigmask

    【讨论】:

      【解决方案3】:

      您始终可以使用 3 个线程,每个函数一个线程加上主线程。

      【讨论】:

      • 不确定这是否能让我在实时线程和阻塞线程之间切换?
      • 如果你阻塞实时线程,那么阻塞线程可以运行,反之亦然。要有条件地阻塞和解除阻塞线程,你可以使用 Mark B 的建议。
      【解决方案4】:

      您需要的是一种排队机制。您的主线程将创建“工作”。然后,您将这些“作业”放到您的积压队列中,您的工作线程将在其中提取并处理它们。当工作完成时。工作线程将现在完成的“作业”放入已完成的队列中。您的主线程可以间歇性地检查已完成的队列,如果有已完成的作业,它将拿起“作业”并对其进行任何需要的操作。然后,您的工作线程进入等待状态,直到下一个作业出现。

      推出队列的方法有很多种。队列可以是一个 unix 管道。一个窗口IO Completion Port 或者您可以使用链表/数组、条件变量和互斥锁推出自己的。

      【讨论】:

        猜你喜欢
        • 2013-03-07
        • 2019-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多