赐教

解决方案 »

  1.   

    一个char类型的变量其实在多线程中无须加锁保护,因为CPU对单个char类型的数据读写本身就是原子性的
      

  2.   

    是这样的吗?char int bool不都是整形么
    一般汇编翻译都是 移进寄存器 修改 移出寄存器 这3步吧 如果这样的话 应该加 为什么就原子了呢?
      

  3.   

    因为CPU对单个char类型的数据读写本身就是原子性的 
    --------------------------------------------
    兄弟不要瞎说啊 InterlockedExchange()
    Interlocked...这系列函数。
      

  4.   

    可以不+锁,但你要保证你你的程序需要的是一个随机度较高的修改,或者是一个线程修改,其他线程读写,的确如上面的兄弟所说"CPU对单个char类型的数据读写本身就是原子性的"
    但你必须保证你对这个变量的修改也是原子性的,比如
    long g_l_Value;//LONG 也可以long chang_value()
    {
        long lmid,lValue;    lmid = g_l_Value;    //用lmid进行一系列运算,将结果保存在lValue之中     g_l_Value = lValue;//单赋值原子操作
        return lValue;
    }g_l_Value = lValue;
    这一句对应的汇编代码是MOV EAX, [lValue];
    MOV [g_l_Value], EAX;
    是的只有两句,在两句之间也可能会被执行其他的赋值,所以要求你的程序需要的是一个随机度较高的修改.
    也就是说,当多个chang_value被执行的时候要求的最终结果只要是根据chang_value被执行只前的某一个g_l_Value运算得到的,而不要求按照一定的时间顺序.
    一定要把lmid = g_l_Value;然后用lmid运算,否则直接用g_l_Value用进行运算,在A线程先后多次对g_l_Value的操作的同时B线程也在同时做类似的操作,结果两个线程交叉影响,用lmid运算就不会有这样的影响.
    lmid = g_l_Value;
    g_l_Value = lValue;
    这两句发生时虽然也会产生交叉影响,但不会影响值的完整性.也就是说,lmid = g_l_Value;不会把g_l_Value被B运算的前一半和C运算的后一半给lmid.
    同理g_l_Value = lValue;也不会影响g_l_Value的完整.
    但要注意对于有时序要求的程序着是不可以的,因为最先运行lmid = g_l_Value;的线程,不一定也最先运行g_l_Value = lValue;
    我个人认为网络上很多人认为凡是"多线程设计就一定要+锁"这种思想是很不全面的,比如我写过一个随机数计算程序,他是多个进程,是的,是进程,我使用了进程数据共享,当然是WIN32下的,没有一个锁,我仍然可以保证不出任何错误,而且可以得到高度随机的数字,我可以保证在至少连续的4096次运算中不会产生两个相同的数据,在实验中,60多万次的运算也没有产生不均衡的数据,这满足了随机要求.
    当然对于某些多线程的指针操作最好+锁和标记,因为内存空间可能回被DELETE.上面这些是一些经验之谈,希望对LZ有用,有用就给分哦!
      

  5.   

    一个char类型的变量其实在多线程中无须加锁保护,因为CPU对单个char类型的数据读写本身就是原子性的
    ===============
    怎么可能呢?为什么对单个char的处理是原子性的呢?
      

  6.   

    14楼说的不错,MOV EAX, [lValue]; 
    MOV [g_l_Value], EAX; 有可能被打断哦。
      

  7.   

    你告诉我什么时候会被打断
    被打断的话MOV [g_l_Value], EAX的值就不是之前计算出的lValue了吗?只要他"是"那么就可以保证
    MOV [g_l_Value], EAX;一句就可以保证g_l_Value的完整性.不要告诉我一句汇编代码会被分到两个时间片里面执行,
    连中断也无法打断单一汇编代码的执行,你说你怎么打断???
    你看明白我说的是什么了吗?
    你真正做过多线程并发访问的实验和项目吗?知道什么是TSS机制吗?
      

  8.   

    window核心编程里的意思是说要加锁,
    但它给的是个long类型
    long g_x = 0;不过char 应该差不多吧。
    看来还是加吧。也懒得去验证了
      

  9.   

    Interlockedxxx操作的就是32位系统上的long(32位整数)
    可见,不管原子不原子,该同步,该加锁还是加了,程序的健壮永远比执行效率重要!
      

  10.   


    #include "stdafx.h"
    #include <Windows.h>char g_x = 0;
    DWORD TreadFun1(PVOID pvParam)
    {
    g_x++; return 0;
    }int TreadFun2(PVOID pvParam)
    {
    g_x++; return 0;
    }int _tmain(int argc, _TCHAR* argv[])
    {
    DWORD dwThreadId1 = 0;
    DWORD dwThreadId2 = 0;
    HANDLE hThread1 = NULL; 
    HANDLE hThread2 = NULL;  hThread1 =   CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)TreadFun1, NULL, 0, &dwThreadId1);
    hThread1 =   CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)TreadFun2, NULL, 0, &dwThreadId1); Sleep(10000);
    return 0;
    }windows核心编程上的问题
    g_x就一定是2吗?
      

  11.   

    要看你的编译器如何对待++
    如果是INC就肯定是2,但其他就可能是1,这要看你做什么,如果你为了计算有多少个线程被运行,你就必须+锁,如果只是为了得到一些数据,那就不用了
      

  12.   

    那么加个volatile 是否可以不加锁呢