mirror of
https://gitee.com/TarsCloud/TarsCpp.git
synced 2025-01-05 17:42:24 +08:00
195 lines
3.8 KiB
C++
Executable File
195 lines
3.8 KiB
C++
Executable File
#include "util/tc_common.h"
|
|
#include "util/tc_cas_queue.h"
|
|
#include "util/tc_thread.h"
|
|
#include "util/tc_autoptr.h"
|
|
#include "util/tc_spin_lock.h"
|
|
#include "util/tc_thread_queue.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
#include <mutex>
|
|
#include <iostream>
|
|
|
|
using namespace tars;
|
|
|
|
class UtilCasTest : public testing::Test
|
|
{
|
|
public:
|
|
//添加日志
|
|
static void SetUpTestCase()
|
|
{
|
|
// cout<<"SetUpTestCase"<<endl;
|
|
}
|
|
static void TearDownTestCase()
|
|
{
|
|
// cout<<"TearDownTestCase"<<endl;
|
|
}
|
|
virtual void SetUp() //TEST跑之前会执行SetUp
|
|
{
|
|
// cout<<"SetUp"<<endl;
|
|
}
|
|
virtual void TearDown() //TEST跑完之后会执行TearDown
|
|
{
|
|
// cout<<"TearDown"<<endl;
|
|
}
|
|
};
|
|
|
|
TEST_F(UtilCasTest, casLock)
|
|
{
|
|
size_t i=0;
|
|
size_t count = 1000000;
|
|
|
|
TC_SpinLock mutex;
|
|
std::thread add([&]{
|
|
int j = count;
|
|
while(j--) {
|
|
TC_LockT<TC_SpinLock> lock(mutex);
|
|
++i;
|
|
}
|
|
});
|
|
|
|
std::thread del([&]{
|
|
int j = count;
|
|
while(j--) {
|
|
TC_LockT<TC_SpinLock> lock(mutex);
|
|
--i;
|
|
}
|
|
});
|
|
|
|
add.join();
|
|
del.join();
|
|
ASSERT_TRUE(i == 0);
|
|
}
|
|
|
|
bool g_terminate = false;
|
|
TC_CasQueue<int64_t> data_cas;
|
|
TC_ThreadQueue<int64_t> data_queue;
|
|
|
|
class WriteThread : public TC_Thread
|
|
{
|
|
protected:
|
|
virtual void run()
|
|
{
|
|
for(int64_t i = 0; i < 100000; i++) {
|
|
data_cas.push_back(i);
|
|
}
|
|
}
|
|
};
|
|
|
|
class ReadThread : public TC_Thread, public TC_HandleBase
|
|
{
|
|
public:
|
|
ReadThread() {}
|
|
|
|
virtual void run()
|
|
{
|
|
int64_t last = -1;
|
|
while(!g_terminate) {
|
|
int64_t i;
|
|
if(data_cas.pop_front(i))
|
|
{
|
|
ASSERT_TRUE(i - last == 1);
|
|
last = i;
|
|
|
|
if(i == 100000-1)
|
|
{
|
|
g_terminate = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
TEST_F(UtilCasTest, casQueue)
|
|
{
|
|
WriteThread w;
|
|
ReadThread r;
|
|
|
|
w.start();
|
|
r.start();
|
|
|
|
w.join();
|
|
r.join();
|
|
}
|
|
|
|
template<typename Q>
|
|
void start(int w, int r, int sleeps, Q &queue_data)
|
|
{
|
|
g_terminate = false;
|
|
|
|
atomic<int64_t> writeIndex {0};
|
|
vector<std::thread*> wthreads;
|
|
for(int i = 0 ; i < w; i++) {
|
|
wthreads.push_back(new std::thread([&]
|
|
{
|
|
while(!g_terminate)
|
|
{
|
|
queue_data.push_back(++writeIndex);
|
|
}
|
|
}));
|
|
}
|
|
|
|
int64_t readIndex = 0;
|
|
|
|
vector<std::thread*> rthreads;
|
|
for(int i = 0 ; i < r; i++)
|
|
{
|
|
rthreads.push_back(new std::thread([&]{
|
|
do{
|
|
int64_t j;
|
|
if(queue_data.pop_front(j))
|
|
{
|
|
readIndex = j;
|
|
}
|
|
else
|
|
{
|
|
if(sleeps > 0)
|
|
{
|
|
TC_Common::msleep(sleeps);
|
|
}
|
|
}
|
|
|
|
}while(!g_terminate);
|
|
}));
|
|
}
|
|
|
|
std::thread print([&]{
|
|
int64_t lastReadIndex = 0;
|
|
int64_t lastWriteIndex = 0;
|
|
while(!g_terminate) {
|
|
cout << "size:" << data_queue.size() << ", write/read index:" << writeIndex/10000. << "/" << readIndex/10000. << ", " << (writeIndex-lastWriteIndex)/10000. << ", " << (readIndex - lastReadIndex)/10000. << endl;
|
|
lastReadIndex = readIndex;
|
|
lastWriteIndex = writeIndex;
|
|
TC_Common::sleep(1);
|
|
}
|
|
});
|
|
|
|
std::thread t([&]{
|
|
TC_Common::sleep(10);
|
|
g_terminate = true;
|
|
});
|
|
t.join();
|
|
print.join();
|
|
for(size_t i = 0; i < wthreads.size(); i++)
|
|
{
|
|
wthreads[i]->join();
|
|
delete wthreads[i];
|
|
}
|
|
for(size_t i = 0; i < rthreads.size(); i++)
|
|
{
|
|
rthreads[i]->join();
|
|
delete rthreads[i];
|
|
}
|
|
}
|
|
|
|
int wThread = 1;
|
|
int rThread = 4;
|
|
int sleepms = 0;
|
|
|
|
TEST_F(UtilCasTest, queueBatch)
|
|
{
|
|
cout << "threadQueueBatch-------------------------------------------" << endl;
|
|
start<TC_ThreadQueue<int64_t>>(wThread, rThread, sleepms, data_queue);
|
|
|
|
cout << "casQueueBatch-------------------------------------------" << endl;
|
|
start<TC_CasQueue<int64_t>>(wThread, rThread, sleepms, data_cas);
|
|
} |