首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个测试应用程序在不同的机器上给出了不同的结果?(关于增量后和线程安全)

为什么这个测试应用程序在不同的机器上给出了不同的结果?(关于增量后和线程安全)
EN

Stack Overflow用户
提问于 2013-05-31 00:16:00
回答 1查看 137关注 0票数 0

我听说有人说像var++和++var这样的语句不是线程安全的,所以我编写了一个应用程序来进行测试。代码如下:

代码语言:javascript
复制
   unsigned long gCounter = 0;
   const unsigned long WORKS = 1048576;  // pow(2, 20)
   const unsigned long MAX_THREADS = 100;
   const unsigned long WORKER_THREADS = 2;

   unsigned long GetCounter(){
           return gCounter++;
   }

   void *WorkerThread(void *){
           unsigned long items = 0;
           do {
                GetCounter();
                items++;
           } while(items < WORKS);

           printf("Exiting thread: %lu\n", pthread_self());
           return NULL;
    }


    int main(int argc, char* argv[]){
         pthread_t workers[MAX_THREADS];

         //create two threads
         for (int i = 0; i < WORKER_THREADS; i++){
            pthread_create(&workers[i], NULL, WorkerThread, NULL);
         }

         //wait for above threads to exit
         for (int i = 0; i < WORKER_THREADS; i++){
               pthread_join(workers[i], NULL);
         }


         assert( gCounter == (WORKER_THREADS * WORKS));
         return 0;
    }

如果增量后操作不是线程安全的,那么上述测试应用程序有时会失败(可能成功)。但令我惊讶的是,在我们的服务器上运行时,它总是在200个测试中成功,而在我的PC上,它却从未成功。

为什么会发生这种事?为什么上面的应用程序总是在我们的服务器上成功呢?下面是关于服务器和我的PC的信息:

代码语言:javascript
复制
     Server machine:
     System: Redhat 3.4.2 - 6.FC3  Kernel: LINUX.2.6.10 
     GCC Version: 3.4.2 20041017   
     CPU: AMD Opteron Processor 144 X86_64

     My PC:
     System: ubuntu 3.2.0-40-generic  Kernel: LINUX.3.4
     GCC Version: 4.6.3 (Ubuntu/Linaro )    
     CPU: Intel(R) Pentium(R) Dual  CPU  T2370        

     Build Command (both are the same, turn off optimization)
     g++ -O0 -o test test.cpp -lpthread

更新

今天我发现--它的CPU是AMDOpteron144的服务器--是一台单cpu单核计算机,也许这就是为什么这个测试应用程序从未在它上失败的原因。据我所知,单cpu单核机器不支持真正的线程并行,线程以非常快的速度运行,它们似乎是并行运行的,但它们确实不是,而且在这种机器上不太可能出现一些线程同步问题。

EN

回答 1

Stack Overflow用户

发布于 2013-05-31 00:25:05

您的代码有未定义的行为,因为它包含数据竞争。

如果一个程序在不同的线程中包含两个相互冲突的操作,至少其中一个不是原子的,并且在另一个线程之前也不会发生,那么程序的执行就包含了一个数据竞赛。任何这样的数据竞争都会导致未定义的行为。 如果其中一个修改内存位置(1.7),而另一个修改或修改相同的内存位置,则[intro.multithread]/4两个表达式计算冲突。

因为您的代码有未定义的行为,所以不能依赖它有任何特定的行为。不要感到惊讶,它总是“工作”在一个平台上,从来没有在另一个平台上工作。

[defns.undefined] 未定义行为:行为,本国际标准对其强制无需求

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16847929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档