15,466
社区成员
发帖
与我相关
我的任务
分享// event1.cpp : Defines the entry point for the console application.
//
// test cases:
// send threads: 2, per thread: 10
// send threads: 20, per thread: 100
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <iomanip>
#include <list>
using namespace std;
//MyPool g_pool;
///////////////////////////////////////////////////////////////////////////////
class MyMutex {
public:
MyMutex();
~MyMutex();
int Lock();
int UnLock();
private:
HANDLE m_object;
};
MyMutex::MyMutex() {
cout << "MyMutex::MyMutex" << endl;
m_object = ::CreateMutex(NULL, FALSE, NULL);
}
MyMutex::~MyMutex() {
cout << "MyMutex::~MyMutex" << endl;
::CloseHandle(m_object);
}
int MyMutex::Lock() {
return (::WaitForSingleObject(m_object, INFINITE) == WAIT_FAILED) ? -1 : 0;
}
int MyMutex::UnLock() {
return (::ReleaseMutex(m_object) == 0) ? -1 : 0;
}
///////////////////////////////////////////////////////////////////////////////
class MyClass {
public:
MyClass(int id);
~MyClass();
int GetID();
private:
int m_id;
};
MyClass::MyClass(int id) {
m_id = id;
}
MyClass::~MyClass() {
}
int MyClass::GetID() {
return m_id;
}
///////////////////////////////////////////////////////////////////////////////
extern MyMutex g_FileLock;
class MyPool {
public:
MyPool();
~MyPool();
MyClass* Get();
void Put(MyClass* p);
private:
list<MyClass*> m_list;
HANDLE m_event;
MyMutex m_lock;
};
MyPool::MyPool() {
cout << "MyPool::MyPool" << endl;
//m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
m_event = ::CreateEvent(NULL, FALSE, FALSE, NULL);
}
MyPool::~MyPool() {
cout << "MyPool::~MyPool" << endl;
::CloseHandle(m_event);
}
MyClass* MyPool::Get() {
MyClass* ret;
DWORD dwRet = -1;
DWORD tid = GetCurrentThreadId();
re:
m_lock.Lock();
while (m_list.size()==0) {
g_FileLock.Lock();
cout << "Thread(" << setw(4) <<tid<<") " << "no node now, waitting... ..." << endl;
g_FileLock.UnLock();
// simulation of pthread_cond_wait
m_lock.UnLock();
//::Sleep(1000);
dwRet = ::WaitForSingleObject(m_event, INFINITE);
if (dwRet==WAIT_OBJECT_0) {
g_FileLock.Lock();
cout <<"Thread(" <<tid<<") " "success return from wait function" << endl;
g_FileLock.UnLock();
goto re;
}
}
ret = *(m_list.begin());
m_list.pop_front();
/*
if (m_list.size()==0) {
m_lock.UnLock();
return NULL;
}
ret = *(m_list.begin());
m_list.pop_front();*/
m_lock.UnLock();
return ret;
}
void MyPool::Put(MyClass* p) {
m_lock.Lock();
m_list.push_back(p);
::SetEvent(m_event);
/*m_list.push_back(p);*/
m_lock.UnLock();
}
///////////////////////////////////////////////////////////////////////////////
MyPool g_pool;
MyMutex g_FileLock;
DWORD WINAPI put_thread(LPVOID arg);
DWORD WINAPI get_thread(LPVOID arg);
DWORD WINAPI put_thread(LPVOID arg) {
int *p = (int*)arg;
DWORD tid = ::GetCurrentThreadId();
int base = *p * 100;
//for (int i=0; i<10; ++i) {
for (int i=base; i<base+100; ++i) {
MyClass* tmp = new MyClass(i);
g_pool.Put(tmp);
g_FileLock.Lock();
cout << "Thread(" <<tid<<") "<<"put::" << i << endl;
g_FileLock.UnLock();
}
delete p;
return 0;
}
DWORD WINAPI get_thread(LPVOID arg) {
DWORD tid = ::GetCurrentThreadId();
while (1) {
MyClass* tmp = g_pool.Get();
if (tmp == NULL) {
g_FileLock.Lock();
cout <<"Thread(" <<tid<<") "<< "no data find" << endl;
g_FileLock.UnLock();
::Sleep(1000);
continue;
}
int i = tmp->GetID();
g_FileLock.Lock();
cout << "Thread(" <<tid<<") "<<"get::" << i << endl;
g_FileLock.UnLock();
delete tmp;
}
}
//MyPool g_pool;
int main(int argc, char* argv[])
{
//MyMutex MyLock;
HANDLE get_thd[20];
HANDLE put_thd[10];
DWORD dwThreadId;
int* tag=NULL;
// put threads, about 64 max threads count
// for (int i=0; i<2000; ++i) { // cant create too much threads
//for (int i=0; i<2; ++i) {
//for (int i=0; i<20; ++i) {
for (int i=0; i<1; ++i) {
tag = new int(i);
put_thd[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
put_thread, // thread function
(LPVOID)tag, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
if (put_thd[i] == NULL) {
g_FileLock.Lock();
fprintf(stderr, "Thread(main) create put thread(%d) error\n", i);
g_FileLock.UnLock();
} else {
g_FileLock.Lock();
fprintf(stderr, "Thread(main) create put thread(%d) success\n", i);
g_FileLock.UnLock();
}
}
// get threads
//for (i=0; i<5; ++i) {
for (i=0; i<3; ++i) {
get_thd[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
get_thread, // thread function
NULL, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
if (get_thd[i] == NULL) {
g_FileLock.Lock();
fprintf(stderr, "Thread(main) create get thread(%d) error\n", i);
g_FileLock.UnLock();
} else {
g_FileLock.Lock();
fprintf(stderr, "Thread(main) create get thread(%d) success\n", i);
g_FileLock.UnLock();
}
}
while (1) ::Sleep(1000);
return 0;
}
///////////////////////////////////////////////////////////////////////////////