Сообщение Re: volatile-only lock от 29.06.2017 16:45
Изменено 29.06.2017 16:51 Кодт
Re: volatile-only lock
Здравствуйте, nikholas, Вы писали:
N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)
Делаем корявый test-and-set
N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)
Делаем корявый test-and-set
struct Request {
int oldvalue, newvalue;
bool done, success;
};
class AtomicVar {
volatile Request* request = nullptr;
int var; // к ней имеет доступ только поток
thread helper = thread([]() {
while (true) {
Request* r = request;
if (!r) {
sleep();
continue;
}
if (var == r->oldvalue) { var = r->newvalue; r->success = true; } else { r->success = false; }
r->done = true;
// все, кто написал в этот момент, - неудачники. ничего, покрутят цикл.
request = nullptr;
}
});
public:
bool test_and_set(int oldvalue, int newvalue) {
Request req = { oldvalue, newvalue, false, false };
request = &req;
while(!req.done && request == &req) sleep(); // либо нашу заявку выполнили, либо перебили, либо выполнили и затем перебили
return req.success;
}
};
Re: volatile-only lock
Здравствуйте, nikholas, Вы писали:
N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)
Делаем корявый test-and-set
N>Написать синхронизацию между потоками, используя только volatile переменные (у которых атомарны только чтение и запись, но не модификация)
Делаем корявый test-and-set
struct Request {
int oldvalue, newvalue;
bool done, success;
};
class AtomicVar {
volatile Request* request = nullptr;
int var; // к ней имеет доступ только поток-помощник
thread helper = thread([]() {
while (true) {
Request* r = request;
if (!r) {
sleep();
continue;
}
if (var == r->oldvalue) { var = r->newvalue; r->success = true; } else { r->success = false; }
r->done = true;
// все, кто написал в этот момент, - неудачники. ничего, покрутят цикл.
request = nullptr;
}
});
public:
bool test_and_set(int oldvalue, int newvalue) {
Request req = { oldvalue, newvalue, false, false };
request = &req;
while(!req.done && request == &req) sleep(); // либо нашу заявку выполнили, либо перебили, либо выполнили и затем перебили
return req.success;
}
};