if语句在判断是否符合条件的同时,是否会被多线程打断?现在不考虑if语句中嵌入调用函数的情况,就是简单的,变量间的比较int a = 0;int main()

  for( int i = 0 ; i < 10 ; ++i)
  {
    hThread = CreateThread(NULL,0,ThreadOne,0,0,0);
    CloseHandle(hThread);
    hThread = CreateThread(NULL,0,ThreadTwo,0,0,0);
    CloseHandle(hThread);
  }
}DWORD WINAPI ThreadOne(PVOID para)
{
  InterLockedExchangeAdd(&a,1);
  if(a == 2)
    return 0;
}DWORD WINAPI ThreadTwo(PVOID para)
{
  InterLockedExchangeAdd(&a,1);
  if(a == 3)
    return 0;
}我想问的是。在线程1执行时,他给全局变量加1后等于2,在进入if语句后。线程二有可能把他抢占过去吗?从而导致比较失败?

解决方案 »

  1.   

    依此类推...WaitForSingleObject这些函数运行期间也可能被打断。 Orz, 多线程必须要出问题了
      

  2.   

    if语句最终的汇编代码只是一条跳转指令(比如JB,JZ等),对于一条指令来说,不存在抢占问题
      

  3.   

    如果是只有一个CPU的情况,肯定是顺序的,取变量a的操作是"原子"的,为了避免变量会因为优化(被寄存器缓存)你需要声明a为volatile,不过如果运行的机器的CPU多于1个的时候,就不好说了
      

  4.   

    那我这样改一下呢,还有没有可能出现线程抢占的可能,因为我的项目,现在比较在乎效率,关键段,最好还是不要用,内核对象的互斥量,事件,尽量不想去使用。关键段好一点。从等待到切换就几百个CPU周期,而内核对象切换一下就1000多个CPU周期,所以我尽量避免使用这些。
    看看我像下面这样改是否会避免线程冲突的可能
    int a = 0;int main()

      for( int i = 0 ; i < 10 ; ++i)
      {
        hThread = CreateThread(NULL,0,ThreadOne,0,0,0);
        CloseHandle(hThread);
        hThread = CreateThread(NULL,0,ThreadTwo,0,0,0);
        CloseHandle(hThread);
      }
    }DWORD WINAPI ThreadOne(PVOID para)
    {
      InterLockedExchangeAdd(&a,1);
      if(InterLocketCompareExchange(&a,2,2) == 2)
      {
        InterLocketExchange
        return 0;
    }DWORD WINAPI ThreadTwo(PVOID para)
    {
      InterLockedExchangeAdd(&a,1);
      if(InterLocketCompareExchange(&a,3,3) == 3)
        return 0;
    }
      

  5.   

    但是If条件呢?就是说,if的条件可能是多条汇编碼。
      

  6.   

    是InterLockedCompareExchange.
    打错一字母。不好意思。。
      

  7.   


    volatile int a = 0; //声明volatileint main()

      for( int i = 0 ; i < 10 ; ++i)
      {
        hThread = CreateThread(NULL,0,ThreadOne,0,0,0);
        CloseHandle(hThread);
        hThread = CreateThread(NULL,0,ThreadTwo,0,0,0);
        CloseHandle(hThread);
      }
    }DWORD WINAPI ThreadOne(PVOID para)
    {
      InterLockedExchangeAdd(&a,1);
      int b = a; //取变量值到局部栈区,避免a的值有变化对函数有影响
      if(b == 2)
        return 0;
    }DWORD WINAPI ThreadTwo(PVOID para)
    {
      InterLockedExchangeAdd(&a,1);
      int b = a;
      if(b == 3)
        return 0;
    }
      

  8.   

    不行的,你用
    EnterCriticalSection(&cs)
    a++;
    if(a == 2){...}
    LeaveCriticalSection()
      

  9.   

    EnterCriticalSection 切进去要几百个CPU周期。切出来也一样,如果等待的线程非常多,那周期可以和内核对象切换有一拼了。所以我尽量用原子的函数操作。
      

  10.   

    除了用关键段,和内核对象同步外,单用Interlocked系统的函数,有没有办法达到不被切换的效果呢。
      

  11.   

    Interlocked系列只是把一些基本的运算原子化,但你现在的情况是把多行代码原子化,这肯定要锁代码段的