就是通常说的"锁",多线程对同一份资源的同步控制,经常用Critical Section,用来锁住一份资源,以免多个线程"同时"访问一份资源。通过下面
4个函数来使用InitializeCriticalSection EnterCriticalSection LeaveCriticalSection DeleteCriticalSection来使用。
需要注意的地方:不要长时间的锁住一份资源,不要在锁住资源而没有释放的时候调用Sleep WaitXXX。如果进入CriticalSection的那个线程当掉了
,而没有离开CriticalSection,系统没有办法将其清掉,因为它不是内核对象,不归操作系统管理。
另一个注意地方:每次调用EnterCriticalSection,会使该CriticalSection的引用计数加1,一个线程可以多次调用EnterCriticalSection,使计数
减1。调用了多少次EnterCriticalSection,就应该调用多少次LeaveCriticalSection。
下面是个考虑了多线程的链表的例子,但也不是完全多线程安全。
4个函数来使用InitializeCriticalSection EnterCriticalSection LeaveCriticalSection DeleteCriticalSection来使用。
需要注意的地方:不要长时间的锁住一份资源,不要在锁住资源而没有释放的时候调用Sleep WaitXXX。如果进入CriticalSection的那个线程当掉了
,而没有离开CriticalSection,系统没有办法将其清掉,因为它不是内核对象,不归操作系统管理。
另一个注意地方:每次调用EnterCriticalSection,会使该CriticalSection的引用计数加1,一个线程可以多次调用EnterCriticalSection,使计数
减1。调用了多少次EnterCriticalSection,就应该调用多少次LeaveCriticalSection。
下面是个考虑了多线程的链表的例子,但也不是完全多线程安全。
1
#include
<
Windows.h
>
2
3 struct Node
4 {
5 int data;
6 struct Node * next;
7 };
8
9 class List
10 {
11 public :
12 List();
13 ~ List();
14
15 public :
16 void InsertNode(Node * pNode, Node * pNewNode);
17 void AddHead(Node * pNode);
18 Node * Next(Node * pNode);
19
20 private :
21 void Init();
22 void Destroy();
23
24 private :
25 Node * m_pHead;
26 CRITICAL_SECTION m_cs;
27 };
2
3 struct Node
4 {
5 int data;
6 struct Node * next;
7 };
8
9 class List
10 {
11 public :
12 List();
13 ~ List();
14
15 public :
16 void InsertNode(Node * pNode, Node * pNewNode);
17 void AddHead(Node * pNode);
18 Node * Next(Node * pNode);
19
20 private :
21 void Init();
22 void Destroy();
23
24 private :
25 Node * m_pHead;
26 CRITICAL_SECTION m_cs;
27 };
1
#include
"
list.h
"
2
3 List::List()
4 {
5 InitializeCriticalSection( & m_cs);
6 Init();
7 }
8
9 List:: ~ List()
10 {
11 Destroy();
12 DeleteCriticalSection( & m_cs);
13 }
14
15 void List::Init()
16 {
17 m_pHead = NULL;
18 }
19
20 void List::Destroy()
21 {
22 Node * pNode;
23 Node * pTemp;
24
25 pNode = m_pHead;
26 while (pNode)
27 {
pTemp = pNode;
28 pNode = pNode -> next;
29 delete pTemp;
30 }
31 }
32
33 void List::InsertNode(Node * pNode, Node * pNewNode)
34 {
35 EnterCriticalSection( & m_cs);
36
37 if (pNode -> next)
38 {
39 pNewNode -> next = pNode -> next;
40 pNode -> next = pNewNode;
41 }
42 else
43 {
44 pNode -> next = pNewNode;
45 }
46
47 LeaveCriticalSection( & m_cs);
48 }
49
50 void List::AddHead(Node * pNode)
51 {
52 EnterCriticalSection( & m_cs);
53 pNode -> next = m_pHead;
54 m_pHead = pNode;
55 LeaveCriticalSection( & m_cs);
56 }
57
58 Node * List::Next(Node * pNode)
59 {
60 Node * pNext;
61
62 EnterCriticalSection( & m_cs);
63 pNext = pNode -> next;
64 LeaveCriticalSection( & m_cs);
65
66 return pNext;
67 }
2
3 List::List()
4 {
5 InitializeCriticalSection( & m_cs);
6 Init();
7 }
8
9 List:: ~ List()
10 {
11 Destroy();
12 DeleteCriticalSection( & m_cs);
13 }
14
15 void List::Init()
16 {
17 m_pHead = NULL;
18 }
19
20 void List::Destroy()
21 {
22 Node * pNode;
23 Node * pTemp;
24
25 pNode = m_pHead;
26 while (pNode)
27 {
pTemp = pNode;
28 pNode = pNode -> next;
29 delete pTemp;
30 }
31 }
32
33 void List::InsertNode(Node * pNode, Node * pNewNode)
34 {
35 EnterCriticalSection( & m_cs);
36
37 if (pNode -> next)
38 {
39 pNewNode -> next = pNode -> next;
40 pNode -> next = pNewNode;
41 }
42 else
43 {
44 pNode -> next = pNewNode;
45 }
46
47 LeaveCriticalSection( & m_cs);
48 }
49
50 void List::AddHead(Node * pNode)
51 {
52 EnterCriticalSection( & m_cs);
53 pNode -> next = m_pHead;
54 m_pHead = pNode;
55 LeaveCriticalSection( & m_cs);
56 }
57
58 Node * List::Next(Node * pNode)
59 {
60 Node * pNext;
61
62 EnterCriticalSection( & m_cs);
63 pNext = pNode -> next;
64 LeaveCriticalSection( & m_cs);
65
66 return pNext;
67 }