В настоящее время я играю с Intel TSX (Transactional Synchronization Extensions), который доступен на более новых чипах Intel Haswell, и я думал о том, как правильно выполнять передачу сигналов между различными потоками. Я попытался использовать условную переменную pthread, и транзакция просто прерывается, что понятно. Тем не менее, кто-нибудь знает какие-либо эффективные способы подать сигнал другому потоку, если текущий внутри транзакции?
void firstThread()
{
if ((status = _xbegin()) == _XBEGIN_STARTED) {
if(someCondition) {
// signal secondThread to wake up
}
}
else {
cerr << "Transaction failed\n";
}
_xend();
}
void secondThread()
{
waitForSignal();
// do something
}
Основным контрактом транзакции является изоляция состояния от других потоков до момента фиксации. В результате вы не сможете делать какие-либо сигналы, оставаясь транзакционными **.
Рассмотрим два потока: один работает без транзакций, ожидающих на барьере, а другой достигает барьера, но выполняет транзакцию. Если нетранзакционный поток продолжается, а затем транзакционный поток откатывается по какой-то независимой причине, то нетранзакционный поток будет работать вхолостую и не может быть возвращен к барьеру после свершившегося факта!
В целом, в модели транзакционного программирования все, что нельзя откатить, должно прервать транзакцию, поэтому вам придется переместить свой сигнальный код за пределы транзакции.
**: в некоторых архитектурах возможны исключения. Транзакционные расширения архитектуры POWER предложить модель приостановки для транзакций, которая позволяет чередовать нетранзакционный и транзакционный код в одном потоке. Однако этой поддержки пока нет в реальном оборудовании, и уж точно не в реализации RTM от Intel.
Других решений пока нет …