Exemple
Un jeu peut vouloir partager les threads qu’il utilise pour la file d’attente de tâches avec d’autres travaux du jeu. L’exemple suivant montre comment utiliser une file d’attente de tâches pour signaler une variable de condition lorsqu’elle contient des éléments à distribuer.// We use condition variables to signal when there's something for us
// in the queue and a bool to signal when we want the whole thing to close.
// Keep all this in a struct for convenient access.
struct QueueControl
{
std::condition_variable workActivity;
std::mutex workMutex;
std::condition_variable completionActivity;
std::mutex completionMutex;
bool terminate = false;
} queueControl;
void CALLBACK TaskQueueNewItemSubmitted(
void* context, XTaskQueueHandle, XTaskQueuePort port)
{
// A new callback has been submitted. Notify the correct condition variable.
QueueControl* queueControl = static_cast<QueueControl*>(context);
switch (port)
{
case XTaskQueuePort::Work:
queueControl->workActivity.notify_all();
break;
case XTaskQueuePort::Completion:
queueControl->completionActivity.notify_all();
break;
}
}
void CreatingTaskQueueWithManualSignaling()
{
// Create a manual task queue.
XTaskQueueHandle queue;
HRESULT hr = XTaskQueueCreate(
XTaskQueueDispatchMode::Manual,
XTaskQueueDispatchMode::Manual,
&queue);
if (FAILED(hr))
{
printf("Creating queue failed: 0x%x\r\n", hr);
return;
}
// Listen to callback-submitted notifications to signal
// our condition variable.
XTaskQueueRegistrationToken token;
hr = XTaskQueueRegisterMonitor(
queue, &queueControl,
TaskQueueNewItemSubmitted, &token);
std::thread workThread([&]()
{
std::unique_lock<std::mutex> lock(queueControl.workMutex);
while (!queueControl.terminate)
{
queueControl.workActivity.wait(lock);
XTaskQueueDispatch(queue, XTaskQueuePort::Work, 0);
}
});
std::thread completionThread([&]()
{
std::unique_lock<std::mutex> lock(queueControl.completionMutex);
while (!queueControl.terminate)
{
queueControl.completionActivity.wait(lock);
XTaskQueueDispatch(queue, XTaskQueuePort::Completion, 0);
}
});
SubmitCallbacks(queue);
// Wait a while for the callbacks to run.
Sleep(1000);
XTaskQueueTerminate(queue, true, nullptr, nullptr);
queueControl.terminate = true;
queueControl.workActivity.notify_all();
queueControl.completionActivity.notify_all();
workThread.join();
completionThread.join();
}
