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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.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
Multithreading 异步while循环的设计模式_Multithreading_Macos_Asynchronous_Grand Central Dispatch - Fatal编程技术网

Multithreading 异步while循环的设计模式

Multithreading 异步while循环的设计模式,multithreading,macos,asynchronous,grand-central-dispatch,Multithreading,Macos,Asynchronous,Grand Central Dispatch,我有一个函数可以归结为: while(doWork) { config = generateConfigurationForTesting(); result = executeWork(config); doWork = isDone(result); } 假设所有函数都是线程安全的,独立于以前的迭代,并且可能需要比允许的最大线程数更多的迭代,我如何重写它以实现高效的异步执行 这里的问题是,我们不知道需要提前进行多少次迭代,因此我们无法创建dispatch\u组或使用dispat

我有一个函数可以归结为:

while(doWork)
{
  config = generateConfigurationForTesting();
  result = executeWork(config);
  doWork = isDone(result);
}
假设所有函数都是线程安全的,独立于以前的迭代,并且可能需要比允许的最大线程数更多的迭代,我如何重写它以实现高效的异步执行

这里的问题是,我们不知道需要提前进行多少次迭代,因此我们无法创建
dispatch\u组
或使用
dispatch\u apply

这是我第一次尝试,但它看起来有点丑陋,因为我随意选择的价值观和睡眠

int thread_count = 0;
bool doWork = true;
int max_threads = 20;  // arbitrarily chosen number

dispatch_queue_t queue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

while(doWork)
{
  if(thread_count < max_threads)
  {
    dispatch_async(queue, ^{ Config myconfig = generateConfigurationForTesting();
                             Result myresult = executeWork();
                             dispatch_async(queue, checkResult(myresult)); });
    thread_count++;
  }
  else
    usleep(100); // don't consume too much CPU
}

void checkResult(Result value)
{
  if(value == good) doWork = false;
  thread_count--;
}
int线程计数=0;
bool-doWork=true;
int max_threads=20;//任意选择数
调度队列=
调度获取全局队列(调度队列优先级默认为0);
while(嫁妆)
{
if(线程数<最大线程数)
{
dispatch_async(队列,^{Config myconfig=generateConfigurationForTesting();
结果myresult=执行作业();
dispatch_async(queue,checkResult(myresult));});
线程计数++;
}
其他的
usleep(100);//不要消耗太多CPU
}
无效检查结果(结果值)
{
如果(值==良好)doWork=错误;
线程计数--;
}

根据您的描述,它看起来像是一种随机化技术,或者是一种生成器,可以进行几乎无限次的配置(因此您的评论是,您不知道提前需要多少次迭代)。作为一个假设,您基本上只能使用您创建的模型,因为您的执行者需要受到关于队列的一些合理假设的限制,并且您不想过度生成,因为这只会在您成功找到
value==good
度量值后延长运行时间

我建议您考虑使用队列(或<代码> OsOxic增量*<代码>和<代码> OsActuiPrimult*>代码>,以保护对<代码> TraceRealCuth< <代码>和<代码> DOWORK 的访问。目前,

thread\u count
递增和递减将发生在两个不同的队列中(主线程的主队列和后台任务的默认队列),因此可以同时递增和递减线程计数。这可能会导致计数不足(这将导致创建的线程数量超出预期)或计数过多(这将导致您永远无法完成任务)


另一个让它看起来更好的选项是让
checkResult
value!的情况下向队列中添加新元素=好的
。这样,您可以使用
dispatch\u apply(20,queue,^{…})
加载队列的初始元素,并且根本不需要
thread\u计数。前20个将使用
dispatch\u apply
(或
dispatch\u apply
认为适合您的配置的金额)添加,然后每次调用
checkResult
时,您可以设置
doWork=false
或将另一个操作添加到
queue
dispatch\u apply()
可以做到这一点,只需将ncpu作为迭代次数传递(apply永远不会使用超过ncpu的工作线程),并在有更多工作要做时保持工作块的每个实例运行(即,循环到
GenerateConfiguration for Testing()
,除非
!doWork
)。

什么是ncpu?假设ncpu是一个大数;您的解决方案使GCD同时运行系统可以处理的尽可能多的线程,并且每个线程作为一个循环运行。找到解决方案后,使用
doWork
完成每个线程,然后
dispatch\u apply()
中的所有线程都将用完。是吗?很抱歉不清楚,ncpu是系统中的CPU数量,例如从
sysctlbyname(“hw.ncpu”,…)
获得。是的,通过这种方法,
dispatch\u apply()
基本上是一种让所有CPU反复运行问题直到找到解决方案的有效方法;但它也可能是一种遗传优化的框架。