标签: race-condition

什么是比赛条件?

编写多线程应用程序时,遇到的最常见问题之一是竞争条件.

我对社区的问题是:

什么是比赛条件?你怎么发现它们?你怎么处理它们?最后,你如何防止它们发生?

concurrency multithreading terminology race-condition

915
推荐指数
11
解决办法
54万
查看次数

!=检查线程是否安全?

我知道复合操作i++不是线程安全的,因为它们涉及多个操作.

但是检查引用本身是一个线程安全的操作?

a != a //is this thread-safe
Run Code Online (Sandbox Code Playgroud)

我尝试编程并使用多个线程,但它没有失败.我想我无法在我的机器上模拟比赛.

编辑:

public class TestThreadSafety {
    private Object a = new Object();

    public static void main(String[] args) {

        final TestThreadSafety instance = new TestThreadSafety();

        Thread testingReferenceThread = new Thread(new Runnable() {

            @Override
            public void run() {
                long countOfIterations = 0L;
                while(true){
                    boolean flag = instance.a != instance.a;
                    if(flag)
                        System.out.println(countOfIterations + ":" + flag);

                    countOfIterations++;
                }
            }
        });

        Thread updatingReferenceThread = new Thread(new Runnable() {

            @Override
            public void run() …
Run Code Online (Sandbox Code Playgroud)

java multithreading atomic thread-safety race-condition

140
推荐指数
6
解决办法
1万
查看次数

为什么代码在线程之间改变共享变量显然不会受到竞争条件的影响?

我正在使用Cygwin GCC并运行此代码:

#include <iostream>
#include <thread>
#include <vector>
using namespace std;

unsigned u = 0;

void foo()
{
    u++;
}

int main()
{
    vector<thread> threads;
    for(int i = 0; i < 1000; i++) {
        threads.push_back (thread (foo));
    }
    for (auto& t : threads) t.join();

    cout << u << endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

用线编译:g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o.

它打印1000,这是正确的.但是,由于线程覆盖了先前增加的值,我预计数量会减少.为什么这段代码不会受到相互访问的影响?

我的测试机器有4个核心,我对我所知道的程序没有任何限制.

当用foo更复杂的东西替换共享的内容时,问题仍然存在,例如

if (u % 3 == 0) {
    u += 4;
} else …
Run Code Online (Sandbox Code Playgroud)

c++ race-condition

107
推荐指数
5
解决办法
1万
查看次数

如何从wordpress数据库中获取最后一个插入的行ID?

我的wordpress插件有一个表,其中包含一个名为ID 的AUTO_INCREMENT主键字段.当一个新行插入表中时,我想获得插入的ID值.

该功能是使用AJAX将数据发布到服务器以插入到数据库中.在AJAX响应中返回新的行ID以更新客户端状态.多个客户端可能同时向服务器发布数据.因此,我必须确保每个AJAX请求获得EXACT新行ID作为响应.

在PHP中,有一个名为mysql_insert_id的方法用于此功能.但是,仅当参数是最后一个操作的link_identifier时,它才对竞争条件有效.我对数据库的操作是在$ wpdb上.如何从$ wpdb中提取link_identifier以确保mysql_insert_id有效?有没有其他方法可以从$ wpdb获取最后插入的行ID?

谢谢.

wordpress auto-increment race-condition

88
推荐指数
2
解决办法
12万
查看次数

django中计数器的原子增量

我试图在Django中以原子方式递增一个简单的计数器.我的代码看起来像这样:

from models import Counter
from django.db import transaction

@transaction.commit_on_success
def increment_counter(name):
    counter = Counter.objects.get_or_create(name = name)[0]
    counter.count += 1
    counter.save()
Run Code Online (Sandbox Code Playgroud)

如果我正确理解Django,这应该将函数包装在事务中并使增量原子化.但它不起作用,并且在计数器更新中存在竞争条件.如何使这些代码成为线程安全的?

python django transactions race-condition

51
推荐指数
5
解决办法
3万
查看次数

私有构造函数,以避免竞争条件

我正在阅读Java Concurrency in Practice4.3.5会议

  @ThreadSafe
  public class SafePoint{

       @GuardedBy("this") private int x,y;

       private SafePoint (int [] a) { this (a[0], a[1]); }

       public SafePoint(SafePoint p) { this (p.get()); }

       public SafePoint(int x, int y){
            this.x = x;
            this.y = y;
       }

       public synchronized int[] get(){
            return new int[] {x,y};
       }

       public synchronized void set(int x, int y){
            this.x = x;
            this.y = y;
       }

  }
Run Code Online (Sandbox Code Playgroud)

我不清楚它在哪里说

私有构造函数的存在是为了避免在复制构造函数实现为此时发生的竞争条件(px,py); 这是私有构造函数捕获习惯的一个例子(Bloch和Gafter,2005).

据我所知,它提供了一个getter,可以在一个数组中同时检索x和y,而不是每个都有一个单独的getter,因此调用者将看到一致的值,但为什么是私有构造函数?这里有什么诀窍

java multithreading race-condition

49
推荐指数
4
解决办法
3431
查看次数

竞赛条件和死锁之间的区别

在编程术语中,死锁和围绕条件的竞争有什么区别?

multithreading deadlock race-condition

47
推荐指数
4
解决办法
3万
查看次数

Postgres中的Atomic UPDATE .. SELECT

我正在建立各种排队机制.有需要处理的数据行和状态标志.我正在使用一个update .. returning条款来管理它:

UPDATE stuff
SET computed = 'working'
WHERE id = (SELECT id from STUFF WHERE computed IS NULL LIMIT 1)
RETURNING * 
Run Code Online (Sandbox Code Playgroud)

嵌套的选择部分是否与更新锁相同,或者我是否有竞争条件?如果是这样,内部选择需要是select for update吗?

postgresql concurrency multithreading race-condition transaction-isolation

46
推荐指数
2
解决办法
2万
查看次数

SQL Server进程队列竞争条件

我有一个订单队列,由多个订单处理器通过存储过程访问.每个处理器都传入一个唯一的ID,用于锁定接下来的20个订单供自己使用.然后,存储过程将这些记录返回给订单处理器以进行操作.

在某些情况下,多个处理器能够检索相同的"OrderTable"记录,此时它们会尝试同时对其进行操作.这最终导致在该过程的后期抛出错误.

我的下一步行动是允许每个处理器获取所有可用的订单并且只是循环处理器,但我希望简单地使这部分代码线程安全,并允许处理器随时抓取记录.

所以明确地 - 任何想法为什么我遇到这种竞争条件以及如何解决问题.

BEGIN TRAN
    UPDATE  OrderTable WITH ( ROWLOCK )
    SET     ProcessorID = @PROCID
    WHERE   OrderID IN ( SELECT TOP ( 20 )
                                        OrderID
                                FROM    OrderTable WITH ( ROWLOCK )
                                WHERE   ProcessorID = 0)
COMMIT TRAN


SELECT  OrderID, ProcessorID, etc...
FROM    OrderTable
WHERE   ProcessorID = @PROCID
Run Code Online (Sandbox Code Playgroud)

sql t-sql sql-server queue race-condition

44
推荐指数
2
解决办法
2万
查看次数

了解goroutines

我试图理解Go中的并发性.特别是,我写了这个线程不安全的程序:

package main

import "fmt"

var x = 1

func inc_x() { //test
  for {
    x += 1
  }
}

func main() {
  go inc_x()
  for {
    fmt.Println(x)
  }
}
Run Code Online (Sandbox Code Playgroud)

我认识到我应该使用频道来防止竞争条件x,但这不是重点.该程序打印1,然后似乎永远循环(没有打印任何更多).我希望它打印一个无限的数字列表,可能会因为竞争条件而跳过一些并重复其他数字(或者更糟糕的是 - 在更新时打印数字inc_x).

我的问题是:为什么程序只打印一行?

需要明确的是:我没有故意使用这个玩具示例的频道.

concurrency go race-condition

41
推荐指数
3
解决办法
8858
查看次数