Windows 多线程编程链表的读写

来源:互联网 发布:线阵音响和矩阵的区别 编辑:程序博客网 时间:2024/06/10 07:46

采用 RWLock结构实现多线程链表的插入,删除以及搜索


//线程类,摘抄Windows 多线程编程的第七章内容

#pragma once
#include <Windows.h>
#include "stdio.h"

typedef struct _RWLock
{
HANDLE hMutex;
HANDLE hDataLock;
int ReadCount;
}RWLock;

class CThreadLock
{
public:
CThreadLock(void);
~CThreadLock(void);


BOOL InitRWLock();
BOOL ReadOK();
BOOL WriteOK();
BOOL AcquireReadLock();
BOOL ReleaseReadLock();
BOOL AcquireWriteLock();
BOOL ReleaseWriteLock();
    BOOL MyWaitForSingleObject(HANDLE hObject);
void Clear();
private:
RWLock *m_pRWLock;
};

#include "ThreadLock.h"

CThreadLock::CThreadLock(void)
{
m_pRWLock = new RWLock;
}

CThreadLock::~CThreadLock(void)
{
if (m_pRWLock != NULL)
{
Clear();
delete m_pRWLock;
}
}

BOOL CThreadLock::InitRWLock()
{
if (m_pRWLock == NULL)return FALSE;
m_pRWLock->ReadCount = 0;


m_pRWLock->hMutex = CreateMutex(NULL,FALSE,NULL);
if (m_pRWLock->hMutex == NULL)
{
return FALSE;
}

m_pRWLock->hDataLock = CreateSemaphore(NULL,1,1,NULL);
if (m_pRWLock->hDataLock == NULL)
{
CloseHandle(m_pRWLock->hMutex);
return FALSE;
}

return TRUE;
}

BOOL CThreadLock::MyWaitForSingleObject(HANDLE hObject)
{
int result;
result = WaitForSingleObject(hObject,MAXIMUM_ALLOWED);

if (result != WAIT_OBJECT_0)
{
//AfxMessageBox(_T("MyWaitForSingleObject - Wait failed, you probably forgot to call release!"));
printf("MyWaitForSingleObject - Wait failed, you probably forgot to call release!\r\n");
}
return (result == WAIT_OBJECT_0);
}

BOOL CThreadLock::ReadOK()
{
printf("ReadOk %d\r\n",m_pRWLock->ReadCount);
return (m_pRWLock->ReadCount > 0);
}


BOOL CThreadLock::WriteOK()
{
DWORD result;


printf("WriteOk %d\r\n",m_pRWLock->ReadCount);
if (m_pRWLock->ReadCount > 1)return FALSE;

result = WaitForSingleObject(m_pRWLock->hDataLock,0);
if (result == WAIT_TIMEOUT)return TRUE;

result = ReleaseSemaphore(m_pRWLock->hDataLock,1,NULL);
if (result == FALSE)
{
printf("WriteOK - ReleaseSemaphore failed\r\n");
}
return FALSE;
}


BOOL CThreadLock::AcquireReadLock()
{
BOOL result = TRUE;

if (!MyWaitForSingleObject(m_pRWLock->hMutex))return FALSE;

if (++m_pRWLock->ReadCount  == 1)
   result = MyWaitForSingleObject(m_pRWLock->hDataLock);
ReleaseMutex(m_pRWLock->hMutex);
return result;
}


BOOL CThreadLock::ReleaseReadLock()
{
int result;
LONG lPrevCount;

if (!MyWaitForSingleObject(m_pRWLock->hMutex))return FALSE;


if (--m_pRWLock->ReadCount == 0)
  result = ReleaseSemaphore(m_pRWLock->hDataLock,1,&lPrevCount);

ReleaseMutex(m_pRWLock->hMutex);
return result;
}


BOOL CThreadLock::AcquireWriteLock()
{
return MyWaitForSingleObject(m_pRWLock->hDataLock);
}

BOOL CThreadLock::ReleaseWriteLock()
{
int result;
LONG lPrevCount;

result = ReleaseSemaphore(m_pRWLock->hDataLock,1,&lPrevCount);
if (lPrevCount != 0)
{
printf("ReleaseWriteLock - Semaphore was not locked!\r\n");
}
return result;
}

void CThreadLock::Clear()
{
CloseHandle(m_pRWLock->hMutex);
CloseHandle(m_pRWLock->hDataLock);
}

//链表类,链表类

#pragma once
#include "ThreadLock.h"

typedef struct sTestList
{
int data;
sTestList *next;
}MyTestList;

class CMyTestList
{
public:
CMyTestList(void);
~CMyTestList(void);

void InitList();
void InsertList(int num);
bool DelteList(int num);
int  SearchList(int index);
bool IsEmpty();
int  GetListSize();
void Clear();
void PrintList();

CThreadLock m_Lock;
private:
MyTestList *head;
};

#include "MyTestList.h"
#include <stdio.h>

CMyTestList::CMyTestList(void)
  :head(NULL)
{
m_Lock.InitRWLock();
}


CMyTestList::~CMyTestList(void)
{
m_Lock.Clear();
}

/*初始化链表*/
void CMyTestList::InitList()
{
if (NULL == head)
{
head = new MyTestList; 
if (NULL == head)return;

head->data = 0;
head->next = NULL;
}
}
/*插入链表*/
void CMyTestList::InsertList(int num)
{
if (NULL == head)return;

MyTestList *temp = head;

if (!m_Lock.WriteOK())return;
while(temp)
{
if (NULL == temp->next)
{
MyTestList *newItem = new MyTestList;
newItem->data = num;
newItem->next = NULL;
temp->next = newItem;
printf("Insert %d\r\n",num);
return;
}
temp = temp->next;//遍历
}
}
//删除链表
bool CMyTestList::DelteList(int num)
{
if (head == NULL)return false;
    MyTestList *pre = head;


if (!m_Lock.WriteOK())return false;


MyTestList *next = pre->next;
while (next)
{
if (next->data == num)
{
pre->next = next->next;
printf("Delete %d\r\n",num);
return true;
}
pre = next;
next = next->next;
}
return false;
}
//搜索链表
int CMyTestList::SearchList(int num)
{
if (head == NULL)return -1;

if (!m_Lock.ReadOK())return -1;

    int size = GetListSize();
if (num < 0 || num > size)return  -1;

MyTestList *temp = head->next;
int i = 0;
while(temp)
{
if (i == num)
{
return temp->data;
}
i++;
temp = temp->next;
}
return -1;
}
//清空链表
void CMyTestList::Clear()
{
if(NULL == head)return;
MyTestList *temp = head;
MyTestList *next = temp->next;
while (next)
{
temp = next;
next = next->next;
delete temp;
}
delete head;
head = NULL;

}
//判断链表是否为空
bool CMyTestList::IsEmpty()
{
if (head->next == NULL)return true; 
return false;
}
//判断链表的大小
int CMyTestList::GetListSize()
{
int size = 0;
MyTestList *temp = head->next;
while (temp)
{
++size;
temp = temp->next;
}
return size;
}

//打印链表
void CMyTestList::PrintList()
{
MyTestList *temp = head->next;

printf("head->");
while (temp)
{
printf("list%d",temp->data);
printf("->");
   temp = temp->next;
}
}


#include "MyTestList.h"

DWORD WINAPI InsertThreadFun(LPVOID n)
{
int i;
CMyTestList *temp = (CMyTestList *)n;
for (i = 0;i < 10;i++)
{
Sleep(1);
temp->m_Lock.AcquireWriteLock();
temp->InsertList(i);
temp->m_Lock.ReleaseWriteLock();
}
return 0;
}

DWORD WINAPI DeleteThreadFun(LPVOID n)
{
int i;
CMyTestList *temp = (CMyTestList *)n;
for (i = 0;i < 2;i++)
{
Sleep(1);
temp->m_Lock.AcquireWriteLock();
temp->DelteList(i);
temp->m_Lock.ReleaseWriteLock();
}
return 0;
}

DWORD WINAPI SearchThreadFun(LPVOID n)
{
int i;
CMyTestList *temp = (CMyTestList *)n;
for (i = 0;i < 5;i++)
{
Sleep(1);
temp->m_Lock.AcquireReadLock();
printf("Search %d\r\n",temp->SearchList(i));
temp->m_Lock.ReleaseReadLock();
}
return 0;
}

int main()
{
    CMyTestList mList;
    mList.InitList();
    HANDLE hThrds[3];


    hThrds[0]  = CreateThread(NULL,0,InsertThreadFun,(LPVOID)&mList,0,NULL);
    hThrds[1]  = CreateThread(NULL,0,DeleteThreadFun,(LPVOID)&mList,0,NULL);
    hThrds[2]  = CreateThread(NULL,0,SearchThreadFun,(LPVOID)&mList,0,NULL);
    DWORD rc;


    rc = WaitForMultipleObjects(3,hThrds,TRUE,INFINITE);

   CloseHandle(hThrds[0]);
   CloseHandle(hThrds[1]);
   CloseHandle(hThrds[2]);
   mList.PrintList();
    return 0;
}


阅读全文
1 0
原创粉丝点击