Data Races
Introduction
Data Race是指在多线程程序中,两个或多个线程同时访问同一个共享变量,且至少有一个线程是写操作。
Data Race并不是某个编程语言的特性,而是Concurrent Execution的特性。
在数据库中也会出现数据竞争的问题,比如两个事务同时对同一个数据进行操作。解决办法是使用Transaction(事务)。
| SQL |
|---|
| BEGIN TRANSACTION;
SELECT @balance = balance FROM accounts WHERE account_id = 12345;
UPDATE accounts SET balance = @balance - 100 WHERE account_id = 12345;
COMMIT TRANSACTION;
BEGIN TRANSACTION;
SELECT @balance = balance FROM accounts WHERE account_id = 12345;
UPDATE accounts SET balance = @balance - 100 WHERE account_id = 12345;
COMMIT TRANSACTION;
|
数据竞争很常见,但只出现在并行模型中,如多线程、分布式系统等。
数据竞争可能导致内存问题,假设p是一个被初始化为NULL的全局指针,那么下面的代码可能会导致错误:
| C |
|---|
| void thread1() {
if(!p) {
p = malloc(128);
}
if(p) {
free(p);
p = NULL;
}
}
void thread2() {
if(!p) {
p = malloc(256);
}
if(p) {
free(p);
p = NULL;
}
}
|
执行这段代码的可能结果是:两边前后分配了不同大小的内存,但后续释放时却只释放了一次,导致内存泄漏;两边同时释放了同一块内存,导致double free;一边已经置空了p,另一边却又释放了p指向的内存,触发未定义行为。
并行程序中的数据竞争问题很难调试,重复运行可能会得到不同的结果。
Intuitive Definition
Data Race以下情况发生:
- 存在不同线程的内存访问操作
- 对同一内存位置的访问
- 至少有一个是写操作
- 两个访问可以自由交错