Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2716366
  • 博文数量: 416
  • 博客积分: 10220
  • 博客等级: 上将
  • 技术积分: 4193
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-15 09:47
文章分类

全部博文(416)

文章存档

2022年(1)

2021年(1)

2020年(1)

2019年(5)

2018年(7)

2017年(6)

2016年(7)

2015年(11)

2014年(1)

2012年(5)

2011年(7)

2010年(35)

2009年(64)

2008年(48)

2007年(177)

2006年(40)

我的朋友

分类: C/C++

2015-02-13 16:06:40

参考:

测试代码:
///////////////////////////////////////////////////////////////////////////////
///                         SIMPLE LOCK FREE STACK                          ///
///           Copyright (c) 2014 Michael Gazonda -           ///
///                              CPOL Licensed                              ///
///       See CPOL.htm, or      ///
///                             ///
///                                 ///
///////////////////////////////////////////////////////////////////////////////
#include
#include
#include
#include
#include
#include
#include
#include "stack.h"
#include "data.h"


// These are the testing parameters, you can change them
#define data_count 10
#define loop_count 1000000
#define thread_count 2
using namespace std;
typedef struct{
double nDataTotal;
float fTotalLast;
int threadId;
    int nActCount;
    int nIndex;
int nLastLen;
int TotalSize;
int ReadSize;
    
clock_t tBegin;
clock_t tEnd;
long tDiff;
}t_help_info;


// This is the test function
// It uses those numbers set at the top


// Using new and delete is part of the test - for our new/delete calls to not crash,
// the data inside the stack must be handled properly. When we don't crash, and there is no
// "lost data", we know that everything went properly when playing with the stack.


thread_local t_help_info help_info;
std::mutex g_mtx;  
void thread_test(stack *s, std::atomic *max_elapsed, std::atomic *empty_count, size_t index)
{
// Initialization - create the data we'll test with
    data  data_;
    data* d_ = &data_;
data* d[data_count];
for (size_t i = 0; i < data_count; ++i){
d[i] = new data;
   d[i]->x_ = index+1;
}


std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();


// This is the test loop
// Push and pop x number of times and see if everything comes out ok on the other side.
// Also a good working sample of moving data into and out of the stack.
for (size_t loop = 0; loop < loop_count; ++loop)
{
for (size_t i = 0; i < data_count; ++i)
{
if (d[i]){
help_info.TotalSize += d[i]->x_;
                s->push(d[i]);
            }
}


for (size_t i = 0; i < data_count; ++i){
//   if (s->pop((node*&)d[i])){
//              help_info.nActCount += d[i]->x_;
//              help_info.ReadSize++;
//          }
            if (s->pop((node*&)d_)){
                help_info.nActCount += d_->x_;
                help_info.ReadSize++;
            }
}
}


    for (size_t loop = 0; loop < loop_count; ++loop)
    {
        if (s->pop((node*&)d_)){
            help_info.nActCount += d_->x_;
            help_info.ReadSize++;
            if (help_info.ReadSize>=data_count * loop_count ) {
              break;
            }
        }
    }


std::chrono::high_resolution_clock::time_point finish = std::chrono::high_resolution_clock::now();
std::chrono::milliseconds span = std::chrono::duration_cast(finish - start);
    //std::unique_lock lock(g_mtx);
std::cout << index << " - thread completed : " << span.count() 
              <<  " read=" << help_info.ReadSize
              <<  " push=" << help_info.TotalSize
              <<  " pop =" << help_info.nActCount << "\r\n";
*max_elapsed = span.count();


// If the test is successful, every location will hold a valid pointer, and no pointers
// will be duplicated. We test for a valid pointer, and by using delete we ensure that we
// didn't have the same data in two places - deleting the same data twice would crash.
// - may not crash on all platforms, so this test isn't meant to have total cross-platform support
for (size_t i = 0; i < data_count; ++i)
{
if (d[i])
delete d[i];
else
(*empty_count)++;
}
}


// This is the place where we get stuff done. Start up the test threads, wait for them, and then
// check the results to display to the user afterwards. No big deal :)
int main(int argc, const char * argv[])
{
std::thread threads[thread_count];
std::atomic max_elapsed{ 0 };
std::atomic empty_count{ 0 };
stack s;


std::cout << R"_(///////////////////////////////////////////////////////////////////////////////
///                         SIMPLE LOCK FREE STACK                          ///
///           Copyright (c) 2014 Michael Gazonda -           ///
///                              CPOL Licensed                              ///
///       See CPOL.htm, or      ///
///                             ///
///                                 ///
///////////////////////////////////////////////////////////////////////////////)_";
std::cout << "\r\nstarting\r\n";


// Start threads
for (size_t i = 0; i < thread_count; ++i)
threads[i] = std::thread(thread_test, &s, &max_elapsed, &empty_count, i);


// Wait for them to all finish
for (size_t i = 0; i < thread_count; ++i)
threads[i].join();


// Output information
size_t operation_count = data_count * loop_count * thread_count * 2;
if (!empty_count)
std::cout << "no lost data\r\n";
else
std::cout << "___lost data count___: " << empty_count << " of " << data_count * thread_count << "\r\n";
std::cout << "thread count         : " << thread_count << "\r\n";
std::cout << "target processor bits: " << PROCESSOR_BITS << "\r\n";
std::cout << "total pushes and pops: " << operation_count << "\r\n";
std::cout << "operations per second: " << operation_count / (max_elapsed.load() > 0 ? max_elapsed.load() : 1) * 1000 << "\r\n";
std::cout << "processing time      : " << max_elapsed.load() << "ms\r\n";
std::cout << "press any key to exit\r\n";
getchar();
    return 0;
}

单线程没有问题,但多线程时则会出现进栈出栈中的x_累计值不相等,

阅读(1286) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~