Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何设置和管理持久多线程?_C_Multithreading - Fatal编程技术网

C 如何设置和管理持久多线程?

C 如何设置和管理持久多线程?,c,multithreading,C,Multithreading,我考虑了POSIX的实现,尽管这个问题更多的是关于架构的 我从一个更新循环开始,它有几个主要的工作要做。我可以将这些作业分为四到五个主要任务,它们有共同的内存访问要求。我的想法是将这些作业分解成它们自己的线程,让它们完成一个“更新”周期,并休眠到下一帧 但是如何同步呢?如果我在每个循环开始时拆下四个或五个线程,让它们运行一次,然后在每次循环中拆下另外4-5个线程?听起来很贵 听起来更合理的做法是创建这些线程一次,让它们进入睡眠状态,直到同步调用将其唤醒 这是明智的做法吗?我愿意接受从想法到任何形

我考虑了POSIX的实现,尽管这个问题更多的是关于架构的

我从一个更新循环开始,它有几个主要的工作要做。我可以将这些作业分为四到五个主要任务,它们有共同的内存访问要求。我的想法是将这些作业分解成它们自己的线程,让它们完成一个“更新”周期,并休眠到下一帧

但是如何同步呢?如果我在每个循环开始时拆下四个或五个线程,让它们运行一次,然后在每次循环中拆下另外4-5个线程?听起来很贵

听起来更合理的做法是创建这些线程一次,让它们进入睡眠状态,直到同步调用将其唤醒

这是明智的做法吗?我愿意接受从想法到任何形式的实现的回应

编辑:根据目前的答案,我想补充:

  • 需要并发性

  • 这些工作线程旨在以非常短的持续时间运行最好是使用任务队列

    任务队列可以看作是等待向其提交作业的线程。如果一次发送多个,则按FIFO顺序执行

    这样,您可以维护4-5个线程,每个线程都执行您提供给它们的作业,而无需为每个作业分离新线程


    唯一的问题是,我不知道C语言中有多少任务队列的实现。苹果公司的Grand Central Dispatch就是这样做的;FreeBSD也有它的一个实现。除了这些,我不知道其他的。(不过,我看起来并不是很努力。)

    最好的方法可能是使用任务队列

    任务队列可以看作是等待向其提交作业的线程。如果一次发送多个,则按FIFO顺序执行

    这样,您可以维护4-5个线程,每个线程都执行您提供给它们的作业,而无需为每个作业分离新线程


    唯一的问题是,我不知道C语言中有多少任务队列的实现。苹果公司的Grand Central Dispatch就是这样做的;FreeBSD也有它的一个实现。除了这些,我不知道其他的。(不过,我看起来不是很努力。)

    这取决于线程执行的任务的粒度。如果他们正在执行长任务(例如,一秒钟或更长时间),那么与线程正在执行的工作相比,创建和销毁线程的成本可以忽略不计,因此我建议保持简单并根据需要创建线程


    相反,如果您有非常短的任务(例如小于10-100毫秒左右),您肯定会开始注意到创建和销毁大量线程的成本。在这种情况下,是的,您应该只创建一次线程,并让它们休眠,直到工作完成。为此,您需要使用某种类型的(例如,
    pthread\u cond\u t
    ):线程等待条件变量,当工作到达时,您向条件变量发送信号。

    ,这取决于线程正在执行的任务的粒度。如果他们正在执行长任务(例如,一秒钟或更长时间),那么与线程正在执行的工作相比,创建和销毁线程的成本可以忽略不计,因此我建议保持简单并根据需要创建线程


    相反,如果您有非常短的任务(例如小于10-100毫秒左右),您肯定会开始注意到创建和销毁大量线程的成本。在这种情况下,是的,您应该只创建一次线程,并让它们休眠,直到工作完成。为此,您需要使用某种类型的(例如,
    pthread\u cond\u t
    ):线程等待条件变量,当工作到达时,您向条件变量发送信号。

    您的想法被称为线程池。它们可以在WinAPI、Intel TBB和Visual Studio ConcRT中找到,我对POSIX了解不多,因此无法帮助您,但如果发布的工作可以拆分,它们是一种具有许多理想特性的优秀结构,例如出色的可伸缩性


    然而,我不会轻视这项工作所花费的时间。如果您有五个任务,并且性能问题非常严重,以至于多个线程是关键,那么创建线程几乎可以忽略不计。

    您的想法被称为线程池。它们可以在WinAPI、Intel TBB和Visual Studio ConcRT中找到,我对POSIX了解不多,因此无法帮助您,但如果发布的工作可以拆分,它们是一种具有许多理想特性的优秀结构,例如出色的可伸缩性


    然而,我不会轻视这项工作所花费的时间。如果您有五个任务,并且您的性能问题非常严重,以至于多个线程是关键,那么创建线程几乎可以忽略不计。

    如果您每个周期都要做相同的工作,并且需要等待所有工作完成后再开始下一个周期,然后你就在考虑正确的解决方案

    您需要一些同步对象:一个“帧开始信号量”、“帧结束信号量”和一个“帧结束事件”。如果每帧有n个独立任务,则启动n个线程,循环如下(伪代码):


    这对小n很有效。如果每个周期需要完成的任务数量变大,那么您可能需要使用一个线程池和一个任务队列,这样您就不会让系统被线程淹没。但是该解决方案更为复杂,而线程复杂度是它的敌人。

    如果您在每个周期都有相同的工作要做,并且需要等待所有工作在下一个周期开始之前完成,那么您正在考虑正确的解决方案

    您需要一些同步对象:一个“帧开始信号量”、“帧结束信号量”和一个“帧结束事件”。如果你有n个
    while true:
      wait on "start of frame semaphore"
      <do work>
      enter lock
      decrement "worker count"
      if "worker count" = 0 then set "end of frame event"
      release lock
      wait on "end of frame semaphore"
    
    while true:
      set "worker count" to n
      increment "start of frame semaphore" by n
      wait on "end of frame event"   
      increment "end of frame semaphore" by n