让线程每个周期调用init一次
Make threads call init once every cycle
我有一个代码,看起来像下面这样,有许多线程执行这个代码片段:
if (!shouldWork)
{
long timeToSleep = 0;
if (FindTimeToSleep(timeToSleep)) {
Sleep(timeToSleep);
InnerInitialize();
}
}
}
现在,函数InnerInitialize应该只在睡眠超时后被调用一次。有许多线程可以睡眠,在他们醒来后,只有一个线程应该调用InnerInitialize。我们可以使用一个简单的信号量,但问题是,在下一个循环中,在所有线程都传递了对InnerInitialize的调用之后,如果线程再次进入睡眠状态,我们可能需要再次调用该函数(只有一次)。这类似于std::call_once,但只是周期性的。
我们如何做到这一点?
应该使用共享互斥锁进行同步。
忽略每个线程如何到达Sleep(timeToSleep)
方法,这是应该发生的:
pthread_mutex_t mutex;
int initialized;
.......
Sleep(timeToSleep);
pthread_mutex_lock(&mutex); //critical section
if (!initialized)
{
intialized = 1;
InnerInitialize();
}
pthread_mutex_unlock (&mutex);
你仍然需要在代码的某个地方重置intialized
变量,但我不完全理解它来帮助你。
当然,这是假设所有线程都在相同的时间内进入睡眠状态,并且这段时间足够长,以保证在所有其他线程醒来之前没有线程(再次)进入睡眠状态。
尝试使用单个线程来管理其余部分。你的,似乎是每个线程组,初始化和会话之间的睡眠将从一个线程管理,而组中的工作线程将在需要时做他们的东西,可能通过作业队列。
在一个"分代计数器"周围同步每个线程,这是一个简单的递增计数器,表示它的变化(通过互斥锁和条件变量)。
当计数器增加时,如果你愿意,这是一个"新的工作日",工人们知道要重新开始。一个单独的、专用的调度线程执行增量和初始化例程,它不需要知道有多少工作线程。
在伪代码:// main / global init
workCycle = new GenerationalCounter() // initialized to _generation 0
// worker thread
myCurrentCycle = 0
while true:
myCurrentCycle = workCycle.awaitNewGeneration(myCurrentCycle)
// lock mutex
// cond_wait until _generation != myCurrentCycle
// fetch _generation for return
// unlock mutex
DoWork()
// scheduler thread
while true:
SleepUntilNextWorkCycle()
InnerIntializer()
workCycle.increment() // lock mutex
// increment _generation
// broadcast
// unlock mutex
通过一点簿记,InnerInitialize()
可以从调度线程中移出,并通过扩展GenerationalCounter
在代增量后释放的第一个线程中运行回调来进入一个工作线程。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 如何强制调用类的全局实例的析构函数和构造函数(以便"re-init"类实例)
- Cocos2d-x、Create_func和init方法,立即调用析构函数
- 为什么支持的init列表在函数调用和构造函数调用中表现不同
- 调用带有支撑init列表的显式构造函数:是否不明确
- 有没有一种方法可以调用init列表中的成员函数
- c++ 11委托的函数是否比c++ 03调用init函数的函数性能差?
- 当返回一个用带括号的init列表初始化的对象时,我保证有一对构造函数和析构函数调用吗?
- 让线程每个周期调用init一次