当前位置: 首页 > 面试题库 >

如何唤醒hibernate的pthread?

顾曾笑
2023-03-14
问题内容

我正在用C++编写程序。我注意到,它获得了许多线程,它们的目的是定期执行某项操作,其中有3或4个线程。我决定通过编写一个调度程序服务来重构,以便使用这些线程的其他地方可以预订该服务,这应该将我随时运行的额外事件线程的数量减少到一个。

我还没有使用此代码的代码。在开始编写之前,我想知道是否有可能,并获得有关我的设计的一些反馈。我要完成的任务的简要说明是这样的:

添加事件

  1. 呼叫者提供事件和时间表
  2. 时间表提供事件的下一次发生
  3. (事件,时间表)对添加到事件队列
  4. 中断睡眠事件线程(即唤醒它)

事件线程主循环

  1. 尝试获取事件队列中的下一个事件
  2. 如果没有未决事件,请直接转到4
  3. 获取应该发生下一个事件的时间
  4. 一直睡到下一个事件(如果没有等待事件,则一直hibernate)
  5. 如果睡眠由于某种原因而中断,请循环回到1
  6. 如果睡眠成功完成,则执行当前事件
  7. 更新队列(删除事件,如果是重复事件,则重新插入)
  8. 跳回1

我已经进行了一些研究,并且知道可以中断睡眠线程,并且我相信,只要防止同时访问事件队列,就不应有任何危险行为。我以为唤醒线程是有可能的,在某些情况下,java的Thread的sleep()调用会引发InterruptedException,并且除非它不依赖于操作系统的基础sleep调用,否则它一定会成为可能。

谁能评论我的方法?这是我最好不要重新发明的轮子吗?具体来说,如何中断正在hibernate的线程,以便在下一条指令处恢复执行,并有可能从被中断的线程中检测到这一点?

关于升压的注意事项

我敢打赌,您可以编写一个带有boost的调度程序,但是由于缺少更好的说法,它可以在一台机器上编译并运行。我之前已经编译了boost程序,并且每个引入boost的文件通常需要30秒钟以上的时间来编译。如果我能避免这种令人烦恼的发展障碍,我非常愿意。

附录-工作守则[根据caf的建议修订]

这是我产生的有效代码。它已经过初步测试,但是可以正确处理单个事件和重复事件,但延迟有所不同。

这是事件线程的主体:

void Scheduler::RunEventLoop()
{
    QueueLock();                   // lock around queue access
    while (threadrunning)
    {
        SleepUntilNextEvent();     // wait for something to happen

        while (!eventqueue.empty() && e.Due())
        {                          // while pending due events exist
            Event e = eventqueue.top();
            eventqueue.pop();

            QueueUnlock();         // unlock
            e.DoEvent();           // perform the event
            QueueLock();           // lock around queue access

            e.Next();              // decrement repeat counter
                                   // reschedule event if necessary
            if (e.ShouldReschedule()) eventqueue.push(e);
        }
    }
    QueueUnlock();                 // unlock
    return;                        // if threadrunning is set to false, exit
}

这是hibernate功能:

void Scheduler::SleepUntilNextEvent()
{
    bool empty = eventqueue.empty();  // check if empty

    if (empty)
    {
        pthread_cond_wait(&eventclock, &queuelock); // wait forever if empty
    }
    else
    {
        timespec t =                  // get absolute time of wakeup
            Bottime::GetMillisAsTimespec(eventqueue.top().Countdown() + 
                                         Bottime::GetCurrentTimeMillis());
        pthread_cond_timedwait(&eventclock, &queuelock, &t); // sleep until event
    }
}

最后,AddEvent:

void Scheduler::AddEvent(Event e)
{
    QueueLock();
    eventqueue.push(e);
    QueueUnlock();
    NotifyEventThread();
}

相关变量声明:

bool threadrunning;
priority_queue<Event, vector<Event>, greater<Event> > eventqueue;
pthread_mutex_t queuelock; // QueueLock and QueueUnlock operate on this
pthread_cond_t eventclock;

为了处理一般事件,每个事件都Event包含一个指向抽象类型对象的指针,该对象的action子类重写action::DoEvent。从内部调用此方法Event::DoEvent
actions由其事件“拥有”,即,如果不再需要重新安排事件,它们将被自动删除。


问题答案:

您正在寻找的是pthread_cond_t对象pthread_cond_timedwaitpthread_cond_wait功能。您可以创建条件变量
isThereAnyTaskToDo 并在事件线程中等待它。添加新事件后,只需使用唤醒事件线程pthread_cond_signal()



 类似资料:
  • 本文向大家介绍HTML5如何唤醒APP?相关面试题,主要包含被问及HTML5如何唤醒APP?时的应答技巧和注意事项,需要的朋友参考一下 有以下几种方式 URL Scheme:最常见 Intent: // :Android Universal Link : iOS, 通过传统的 HTTP 链接即可打开 APP 唤醒途径 iframe的src a标签的src window.location 参考资料:

  • 下面我们来看看睡眠和醒来的基本模型。假设有两个系统调用作为睡眠和唤醒。呼叫睡眠的过程将被阻止,而调用的过程将被唤醒。 有一个叫做生产者消费者问题的流行例子,它是模拟睡眠和唤醒机制的最流行的问题。 睡眠和觉醒的概念非常简单。如果关键部分不是空的,那么该过程将进入休眠状态。它将被临界区内正在执行的其他进程唤醒,以便进程可以进入临界区。 在生产者消费者问题中,让我们说有两个过程,一个过程写某事,而另一个

  • 休眠与唤醒 [HW,ACPI] acpi_sleep={s3_bios,s3_mode,s3_beep,s4_nohwsig,old_ordering,nonvs,sci_force_enable} ACPI休眠选项。 (1)s3_bios和s3_mode与显卡有关。计算机从S3状态(挂起到内存)恢复时,硬件需要被正确的初始化。这对大多数硬件都不是问题,但因为显 卡是由BIOS初始化的,内核无法获

  • Future 一次polled 就能完成的,并不常见。而多数情况下,Future 需要确保一旦准备好前进,就再次进行轮询(poll) 。而这是通过Waker类型,辅助完成的。 每次 Future poll 时,都会将其作为“任务(task)”的一部分。任务是已提交给 executor 的顶级 Future 。 Waker提供一个wake()方法,它可以用来告诉 executor,应该唤醒的相关任务

  • 问题内容: 我有以下方法: 从视图中调用它: 如您所见,_attempt方法期望actor为type ,但是该对象似乎为type 。为什么会这样呢?更重要的是,如何将(显然是User对象的一种包装器)转换为对象? 有关更多信息,请参见:https : //docs.djangoproject.com/en/dev/ref/request- response/#django.http.HttpReq

  • 当 M600 智能手表短时未使用时,它的屏幕将自动变暗。您也可手动调暗屏幕。 若要调暗屏幕 将手掌放在屏幕上直至此手表振动。 若要唤醒屏幕 轻触屏幕 或 在您的前方快速抬高 M600。 或 短时按下任一按钮。 请注意,调暗屏幕适用于 Always-on screen(保持启用屏幕)功能打开时。如 Always-on screen(保持启用屏幕)功能关闭,当 M600 智能手表未使用一段时间时,它的