VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 126|回复: 4

[已解决]高级班-多线程-[6]线程间的同步机制课程中,向全局数组加入成员时,并非按顺序加入!

[复制链接]
63_avatar_middle
最佳答案
1 
donate_vip 发表于 2020-4-27 22:47:16 | 显示全部楼层 |阅读模式
本帖最后由 safeboy 于 2020-4-27 22:47 编辑

高级班-多线程-[6]线程间的同步机制课程中,向全局数组加入成员时,并非按顺序加入
在实际应用中极可能造成出错,请问有什么方式可以解决?
全局变量定义:
  1. CStringArray g_strAry;  //MFC中 的CArray类 中的 CStringArray 动态数组中
  2. CRITICAL_SECTION g_CriSec; //定义一个  全局的多线程 关键区(许可证)
复制代码

线程函数:
  1. UINT __cdecl MoreThreadProc(LPVOID pParam)
  2. {
  3.         //主进程传递进来 10 20 30 ~ 500的序号
  4.         int startIdx = (int)pParam;
  5.         //从传递的序号开始 循环加100次
  6.         // 10 11 12 ~ 109
  7.         // 20 21 22 ~ 119
  8.         for (int i=startIdx;i<startIdx+100;++i)
  9.         {

  10.                 CString strNum;
  11.                 strNum.Format(_T("%d"), i);
  12.                 EnterCriticalSection(&g_CriSec);
  13.                 g_strAry.Add(strNum);
  14.            //g_strAry2.Add(strNum);
  15.            //g_strAry3.Add(strNum);
  16. //不要设置多个CriticalSection
  17. //可以将需要操作的多个全局变量都放在
  18. //只需要在有对全局变量操作的代码,才需要开启多线程许可机制
  19. //或者说在Enter 和 Leave 之间不要执行时间太长的代码
  20.                 LeaveCriticalSection(&g_CriSec);
  21.         }
  22.         return 0;
  23. }
复制代码

线程启动代码:
  1. void CMoreThreadDlg::OnBnClickedBtnMorethread()
  2. {
  3.         InitializeCriticalSection(&g_CriSec); //初始化关键区(许可证)

  4.         for (int i=1;i<=50;++i)
  5.         {
  6.                 CWinThread* pThread = AfxBeginThread(MoreThreadProc, (LPVOID)(i * 10));
  7.                 //启动50条线程,且传递 10 20 30~ 500的序号给线程函数
  8.         }
  9. }
复制代码

检索全局动态数组代码:
  1. void CMoreThreadDlg::OnBnClickedBtnResult()
  2. {
  3.         int arryCount = g_strAry.GetCount();
  4.         CString strAryCount;
  5.         strAryCount.Format(_T("%d"), arryCount);
  6.         if (MessageBox(_T("当前数组总数为:")+strAryCount,_T("是否要读取全部数组成员?"),MB_OKCANCEL)==IDOK)
  7.         {
  8.                 for (int i=0;i<arryCount;++i)
  9.                 {
  10.                         m_edt_status.SetSel(-1);
  11.                         m_edt_status.ReplaceSel(g_strAry.GetAt(i)+_T("\r\n"));
  12.                 }
  13.         }
  14.         DeleteCriticalSection(&g_CriSec); //不要忘记退出关键区(许可证)
  15. }
复制代码

打印到编辑中的结果:

高级班-多线程-[6]线程间的同步机制课程中,向全局数组加入成员时,并非按顺序加入!
最佳答案
51_avatar_small
2020-4-28 16:56:09
safeboy 发表于 2020-4-28 11:27
后来用课程小作业提到的 用MFC封装的类CCriticalSection 来实现多线程,也是一样顺序是混乱的,因为归终结 ...

这个东西本身就是异步的,靠关键区来进行线程同步,谁抢到了就谁先写入,所以可以保证同一时间只能是一个线程往 CStringArray 数组中插,但是无法保证是按照指定的顺序。




上一篇:各位大佬,麻烦帮我看一下QT中国象棋的问题
下一篇:在Windows编程编写第一个实例的时候,为什么链接不到windows.h这个头文件啊啊啊啊
63_avatar_middle
最佳答案
1 
ico_lz  楼主| 发表于 2020-4-28 11:27:26 | 显示全部楼层
后来用课程小作业提到的 用MFC封装的类CCriticalSection 来实现多线程,也是一样顺序是混乱的,因为归终结底还是以上代码实现的,只是将初始化函数放在类的构造函数中,把删除函数房子析构函数中而已。
51_avatar_middle
最佳答案
79 
online_admins 发表于 2020-4-28 16:56:09 | 显示全部楼层    本楼为最佳答案   
bestAnswer
safeboy 发表于 2020-4-28 11:27
后来用课程小作业提到的 用MFC封装的类CCriticalSection 来实现多线程,也是一样顺序是混乱的,因为归终结 ...

这个东西本身就是异步的,靠关键区来进行线程同步,谁抢到了就谁先写入,所以可以保证同一时间只能是一个线程往 CStringArray 数组中插,但是无法保证是按照指定的顺序。
63_avatar_middle
最佳答案
1 
ico_lz  楼主| 发表于 2020-4-28 23:12:22 | 显示全部楼层
Syc 发表于 2020-4-28 16:56
这个东西本身就是异步的,靠关键区来进行线程同步,谁抢到了就谁先写入,所以可以保证同一时间只能是一个 ...

好的,谢谢老师,如果真的要按顺序,可能可以用别的方法,将需要插入数组本身就对应好编号,然后用数组排列的方式来实现?
51_avatar_middle
最佳答案
79 
online_admins 发表于 2020-4-29 08:59:58 | 显示全部楼层
safeboy 发表于 2020-4-28 23:12
好的,谢谢老师,如果真的要按顺序,可能可以用别的方法,将需要插入数组本身就对应好编号,然后用数组排 ...

嗯,可以先插入,都插入完了之后再重新排下序也是可以的!
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

×【发帖 友情提示】
1、请回复有意义的内容,请勿恶意灌水;
2、纯数字、字母、表情等无意义的内容系统将自动删除;
3、若正常回复后帖子被自动删除,为系统误删的情况,请重新回复其他正常内容或等待管理员审核通过后会自动发布;
4、感谢您对VC驿站一如既往的支持,谢谢合作!

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号 )|网站地图wx_jqr

GMT+8, 2020-7-14 15:49

Powered by CcTry.CoM

© 2009-2020 cctry.com

快速回复 返回顶部 返回列表