分享

VS2010实现多线程同步

 禁忌石 2017-04-18

VS2010实现多线程同步

zzwhjj 发布于 2013年08月05日 17时, 1评/4135阅
分享到: 
VS2010实现多线程同步实例
标签: <无>

代码片段(2)[全屏查看所有代码]

1. [代码]多线程同步     跳至 [1] [全屏预览]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
//根据线程句柄获取当前任务在列表视图控件中的位置
void CMultiThreadDlg::FindItemPos(HANDLE hHandle, int &nPos, POSITION &pos,
                                                   bool &bTerminate)
{
    pos = m_hHandleList.GetHeadPosition();//获取头节点位置
    while (pos != NULL)
    {
        //获取节点元素数据
        CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
        if (pParam != NULL)
        {
            if (pParam->hHandle == hHandle)
            {
                nPos = pParam->nPos;
                bTerminate = pParam->bStop;
                return;
            }
        }
        m_hHandleList.GetNext(pos);
    }
    nPos = -1;
}
 
//在删除项目后更新HandleList列表
void CMultiThreadDlg::UpdateHandleList(int nPos)
{
    POSITION pos = m_hHandleList.GetHeadPosition();
    while (pos != NULL)
    {
        CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
        if (pParam != NULL)
        {
            if (pParam->nPos > nPos)
            {
                pParam->nPos--;
            }
        }
        m_hHandleList.GetNext(pos);
    }
}
 
//线程函数
DWORD __stdcall TaskProc(LPVOID lpParameter)
{
    CThreadParam param; //定义线程参数
    memcpy(&param, (CThreadParam *)lpParameter, sizeof(CThreadParam));
    char szCounter[10] = {0};
    int nPos = 0;
    POSITION pos;
    bool bTerminate = false;
 
    for (int i=0; i<500; i++)
    {
        memset(szCounter, 0, 10);
        _itoa_s(i, szCounter, 10);
        //获取当前位置对应列表视图中的项目位置
        param.pDlg->FindItemPos(param.hHandle, nPos, pos, bTerminate);
        if (nPos != -1)
        {
            //在列表视图中设置计数
            param.pDlg->m_listTask.SetItemText(nPos, 1, (CString)szCounter);
        }
        if (bTerminate)//如果线程被提前终止
        {
            goto label;
        }
        Sleep(100);//延时,演示任务进行中
    }
label://线程结束后删除列表中的任务
    //线程同步,不允许多个线程同时执行该操作
    WaitForSingleObject(param.pDlg->m_hEvent, INFINITE);
    //根据线程句柄查找项目
    param.pDlg->FindItemPos(param.hHandle, nPos, pos, bTerminate);
    if (nPos != -1)
    {
        param.pDlg->m_listTask.DeleteItem(nPos);
        //获取m_listTask链表中对应的节点数据
        CThreadParam *pItem = (CThreadParam *)param.pDlg->m_hHandleList.GetAt(pos);
        param.pDlg->m_hHandleList.RemoveAt(pos);
        if (pItem != NULL)
        {
            delete pItem;
        }
        param.pDlg->UpdateHandleList(nPos);
    }
    SetEvent(param.pDlg->m_hEvent);//将事件设置为有信号状态
    if (param.pDlg->m_listTask.GetItemCount() < 1)
    {
        if (param.pDlg->m_bExitProcess)
        {
            exit(0);
        }
    }
    return 0;
}
 
//新任务
void CMultiThreadDlg::OnBnClickedNewTask()
{
    CThreadParam *pParam = new CThreadParam;//定义一个线程参数
    pParam->pDlg = this; //关联对话框
    int nCount = m_listTask.GetItemCount();
    int nPos = m_listTask.InsertItem(nCount, _T("任务"), 0);
    CString strText;
    strText.Format(_T("任务%d"), nPos);
    m_listTask.SetItemText(nPos, 0, strText);
    m_listTask.SetItemText(nPos, 2, _T("进行中..."));
    pParam->nPos = nPos;
    pParam->hHandle = CreateThread(NULL, 0, TaskProc, pParam, 0, NULL);//创建线程
    m_hHandleList.AddHead(pParam);//将线程参数添加到列表中
}
 
//暂停
void CMultiThreadDlg::OnBnClickedPause()
{
    int nSel = m_listTask.GetSelectionMark();//获取用户选中的选项
    if (nSel != -1)
    {
        CString strState = m_listTask.GetItemText(nSel, 2);
        if (strState == _T("暂停"))
        {
            return;
        }
        POSITION pos = m_hHandleList.GetHeadPosition();
        while (pos != NULL)
        {
            CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
            if (pParam != NULL)
            {
                if (pParam->nPos == nSel)
                {
                    SuspendThread(pParam->hHandle);//挂起线程
                    m_listTask.SetItemText(nSel, 2, _T("暂停"));
                    return;
                }
            }
            m_hHandleList.GetNext(pos);
        }
    }
}
 
//继续
void CMultiThreadDlg::OnBnClickedContinue()
{
    int nSel = m_listTask.GetSelectionMark();
    if (nSel != -1)
    {
        CString strState = m_listTask.GetItemText(nSel, 2);
        if (strState == _T("暂停"))
        {
            POSITION pos = m_hHandleList.GetHeadPosition();
            while (pos != NULL)
            {
                //获取节点数据
                CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
                if (pParam != NULL)
                {
                    if (pParam->nPos == nSel)
                    {
                        ResumeThread(pParam->hHandle);//唤醒线程
                        m_listTask.SetItemText(nSel, 2, _T("进行中..."));
                        return;
                    }
                }
                m_hHandleList.GetNext(pos);
            }
        }
    }
}
 
//终止
void CMultiThreadDlg::OnBnClickedStop()
{
    int nSel = m_listTask.GetSelectionMark();
    if (nSel != -1)
    {
        POSITION pos = m_hHandleList.GetHeadPosition();
        while (pos != NULL)
        {
            CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
            if (pParam != NULL)
            {
                if (pParam->nPos == nSel)
                {
                    if (!pParam->bStop)
                    {
                        pParam->bStop = true;
                    }
                    return;
                }
            }
            m_hHandleList.GetNext(pos);
        }
    }
}
 
//继续所有暂停的任务
void CMultiThreadDlg::ContinueAllTask()
{
    POSITION pos = m_hHandleList.GetHeadPosition();
    while (pos != NULL)
    {
        CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
        if (pParam != NULL)
        {
            if (!pParam->bStop)
            {
                ResumeThread(pParam->hHandle);//唤醒线程
            }
        }
        m_hHandleList.GetNext(pos);
    }
}
 
void CMultiThreadDlg::OnCancel()
{
    POSITION pos = m_hHandleList.GetHeadPosition();
    if (pos != NULL)
    {
        CDialogEx::OnCancel();
        return;
    }
    ContinueAllTask();//恢复所有任务
    m_bExitProcess = TRUE;
    while (pos != NULL)
    {
        CThreadParam *pParam = (CThreadParam *)m_hHandleList.GetAt(pos);
        if (pParam != NULL)
        {
            if (!pParam->bStop)
            {
                pParam->bStop = true;
            }
        }
        m_hHandleList.GetNext(pos);
    }
 
    CDialogEx::OnCancel();
}

2. [文件] C++多线程同步.rar ~ 130KB     下载(227)     

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多