导致比赛条件在我没有源但可以加载DLL的程序中?

时间:2012-02-08 21:56:34

标签: c++ c multithreading race-condition

所以最近我开始考虑一种在DLL可扩展的程序中提高速度(vs cpu使用率)的方法,你可以用C ++中提供的SDK(软件开发工具包)构建它。

我开始研究线程数据,然后写入全局变量,其中 - 如果需要 - 主线程只调用一个变量,而不执行整个函数(线程完成这些工作)。

我的结果让我感到惊讶,因为我预计线程会使应用程序崩溃 - 但事实并非如此。

我开始讨论应用程序的开发者论坛 - 我们达到了这样的观点: “线程的规则是:如果它崩溃,那就错了,如果没有崩溃,它可能仍然是错误的。”和: “实际上,该代码可能不会崩溃,但它可能会破坏变量。我听说过多线程程序运行数月的故事,在发生种族危害之前没有任何问题。”

嗯,'GETS'实际上会导致竞争条件吗?

主要应用程序(SA-MP,San Andreas Multiplayer)是单线程的,并且这样编译。

我用于测试的代码: [C ++]

#ifdef OS_WINDOWS
    void Thread::BackgroundCalculator( void *unused )
#else
    void *Thread::BackgroundCalculator( void *unused )
#endif
{
    float X;
    float Y;
    float Z;
    while( true )
    {
        if(ENABLED == false)
        {
            continue;
        }
        for(int i = 0; i < MAX_PLAYERS; ++i)
        {
            if(IsPlayerConnected(i) == false)
            {
                speed[i] = -1.0f;
                continue;
            }
            if(IsPlayerInAnyVehicle(i) == true)
            {
                GetVehicleVelocity(GetPlayerVehicleID(i),&X,&Y,&Z);//Is actually used by MAIN APPLICATION thread too... so should cause race condition?
            }
            else
            {
                GetPlayerVelocity(i,&X,&Y,&Z);//Is actually used by MAIN APPLICATION thread too... so should cause race condition?
            }
            speed[i] = sqrt(X*X+Y*Y+Z*Z);//called from my code.. thread
        }
        SLEEP(30);
    }

    EXIT_THREAD();//should be never reached..
}

static cell AMX_NATIVE_CALL n_GetSpeed( AMX* amx, cell* params )
{
    return amx_ftoc(speed[params[1]]);//returning to main thread, ftoc = FloatToCell
}

当从虚拟机(.amx文件)调用非常多的时间“n_GetSpeed”时。它没有崩溃。 我也尝试尽可能多地从主线程和我的线程调用GetPlayerVelocity / GetVehicleVelocity。并且仍然没有崩溃。完全不是我所期待的。

所以,当我们达到有人说会出现竞争状态的时候,我想知道如何引发竞争条件(强迫竞争条件?)。 (在C / C ++课程中)

__

我正在制作的代码始终是开源的,可从我的页面获取,这也是: http://gpb.googlecode.com/files/ThreadTest_R100.zip 只要你需要整个代码;)

__

额外注意事项:事情是..我只访问变量,而不是更改,我唯一改变的是速度变量,它只在第二个线程中完成。

1 个答案:

答案 0 :(得分:2)

不了解您正在修改的应用程序。它可能会导致崩溃。

你说你只读,所以一切都应该没问题。但是,主线程(原始程序)肯定会改变变量。可能发生的一件事是,在你调用IsPlayerInAnyVehicle并且它返回TRUE后,它会变为FALSE,或者车辆发生变化,或者玩家死亡,或者玩家退出,......因此,你对GetVehicleVelocity,GetPlayerVehicleID或GetPlayerVelocity的调用可能是在错误的情况下打电话。这会导致崩溃吗?谁知道。但至少,代码不是100%健康。

编辑:如果不知道你调用的方法是如何实现的,就不可能知道这段代码是否是线程安全的。将弱内存排序放入游戏中,所有赌注都关闭,没有适当的内存障碍。