C ot强制线程从外部等待,而不挂起线程来注入等待代码;如果SuspendThread对您不起作用,那么这对您没有帮助

C ot强制线程从外部等待,而不挂起线程来注入等待代码;如果SuspendThread对您不起作用,那么这对您没有帮助,c,multithreading,winapi,visual-studio-2010,C,Multithreading,Winapi,Visual Studio 2010,最接近信号的可能是QueueUserAPC,它将安排回调在线程下一次进入“可警报等待状态”时运行,例如通过调用SleepEx或WaitForSingleObjectEx或类似方法。@Anthony W-感谢您的建议。我正在运行Win32线程,这些线程以高于正常线程的优先级模拟实时任务,并以最高线程的优先级运行伪中断处理程序和tick中断生成器。被挂起的线程我正在更改为线程\u优先级\u空闲,以防有任何不同。我刚刚尝试了你的建议,使用线程优先级时间关键,但不幸的是,这没有任何区别 关于你的问题,我

最接近信号的可能是
QueueUserAPC
,它将安排回调在线程下一次进入“可警报等待状态”时运行,例如通过调用
SleepEx
WaitForSingleObjectEx
或类似方法。

@Anthony W-感谢您的建议。我正在运行Win32线程,这些线程以高于正常线程的优先级模拟实时任务,并以最高线程的优先级运行伪中断处理程序和tick中断生成器。被挂起的线程我正在更改为线程\u优先级\u空闲,以防有任何不同。我刚刚尝试了你的建议,使用线程优先级时间关键,但不幸的是,这没有任何区别

关于你的问题,我确信暂停和恢复不立即发生是问题所在——不,我不是。在我不熟悉的环境中,这是我最好的猜测。我对暂停和恢复工作失败的思考源于我在任务完成时的观察。如果我调用yield(发出信号[使用Win32事件]一个更高优先级的Win32线程以切换到下一个实时任务),我可以在yield之后放置一个断点,该断点在更高优先级线程的断点之前到达。目前尚不清楚是事件和更高优先级任务运行的信令延迟,还是挂起线程和线程实际停止运行的延迟导致了这一问题,但确实观察到了这种行为。这是使用信号量握手修复的,但对于由滴答声中断引起的抢占,这是无法做到的

我知道模拟没有像我预期的那样运行,因为一组检查实时任务调度顺序的测试失败了。调度程序总是可能有问题,或者测试有问题,但是测试将运行数周而不会在实时目标上失败,所以我倾向于认为测试和调度程序是正常的。一个很大的区别是在实时目标上,滴答声的频率是1毫秒,而在Win32模拟目标上,滴答声的频率是15毫秒,即使在那时也有很大的变化

@雷米-我今天已经读了很多关于光纤的书,我的结论是,在协作模式下模拟调度器是完美的。但是,据我所知,它们只能由光纤本身调用SwitchToFiber()函数来调度。可以让线程阻塞计时器或睡眠,使其周期性运行,从而有效地抢占当时正在运行的光纤吗?从我读到的答案是否定的,因为阻塞一根光纤将阻塞线程中运行的所有光纤。如果可以让它工作,那么周期性执行的光纤是否可以调用SwitchToFiber()函数来选择下一个要运行的光纤,然后再休眠一段固定的时间?我再次认为答案是否定的,因为一旦它切换到另一个光纤,它将不再执行,因此在下次执行光纤切换回它之前,它不会真正调用Sleep()函数。如果我对纤维的工作原理有错误的认识,请纠正我的逻辑


我认为,如果周期性功能可以保留在它自己的线程中,与执行光纤的线程分离,那么它就可以工作——但是(同样从我所读到的内容来看),我不认为一个线程可以影响在不同线程中运行的光纤的执行。如果我的结论是错误的,如果您能在这里纠正我的结论,我将再次表示感谢。

[p>[EDIT]-比下面的黑客更简单-似乎只是确保所有线程都在同一个CPU内核上运行也解决了问题:o)之后。唯一的问题是CPU的运行速度接近100%,我不确定高温是否会损坏它。 [/编辑]

啊哈!我想我有办法解决这个问题,但这很难看。不过,丑陋仍保留在端口层

我现在要做的是在每次创建线程以运行任务时存储线程ID(为每个创建的实时任务创建Win32线程)。然后我添加了下面的函数-使用跟踪宏调用该函数。跟踪宏可以被定义为执行任何您想要的操作,并且在这种情况下被证明非常有用。下面代码中的注释解释了这一点。模拟并不完美,当线程调度已经偏离实时调度时,所有这一切都会纠正线程调度,而我希望它一开始不会出错,但跟踪宏的定位使包含此解决方案的代码通过了所有测试:

void vPortCheckCorrectThreadIsRunning( void )
{
xThreadState *pxThreadState;

    /* When switching threads, Windows does not always seem to run the selected
    thread immediately.  This function can be called to check if the thread
    that is currently running is the thread that is responsible for executing
    the task selected by the real time scheduler.  The demo project for the Win32
    port calls this function from the trace macros which are seeded throughout 
    the real time kernel code at points where something significant occurs.
    Adding this functionality allows all the standard tests to pass, but users
    should still be aware that extra calls to this function could be required
    if their application requires absolute fixes and predictable sequencing (as
    the port tests do).  This is still a simulation - not the real thing! */
    if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
    {
        /* Obtain the real time task to Win32 mapping state information. */
        pxThreadState = ( xThreadState * ) *( ( unsigned long * ) pxCurrentTCB );

        if( GetCurrentThreadId() != pxThreadState->ulThreadId )
        {
            SwitchToThread();
        }
    }
}

但是光纤不会同时在多芯上运行。谢谢你的提示。明天我会查一些关于纤维的参考资料。@Zan:一根线可以有多条纤维,你可以有多条线,每根线芯一条。是的,你可以有多条线+每条线有多条纤维。但是,您无法从线程外部控制哪个光纤在该线程上运行。可能不是实时的,但您通常可以在外部调度光纤。线程负责调度自己的光纤,在同一线程中运行的光纤可以相互调度。要让线程调度特定的光纤,只需向线程发送某种通知(线程消息、队列等),然后线程(或该线程中的光纤)就可以在处理通知时调度请求的光纤。