①、线程同步的必要性:
 
int g_Num = 0;
UINT __cdecl ThreadProc(LPVOID lpParameter)
{
 for (int idx = 0; idx < 100; ++idx) {
  g_Num = g_Num+1;
  CString strNum;
  strNum.Format(_T("%d"), g_Num);
  g_Num = g_Num-1;
 }
 return 0;
}
 
void CThreadTestDlg::OnBnClickedBtn()
{
 for (int idx = 1; idx <= 50; ++idx) {
  AfxBeginThread(ThreadProc, NULL);
 }
}
void CThreadTestDlg::OnBnClickedPrintBtn()
{
 int realNum = g_Num;
}
 
///////////////////////////////////////////////////////////////////////////////
 
CStringArray g_ArrString;
UINT __cdecl ThreadProc(LPVOID lpParameter)
{
 int startIdx = (int)lpParameter;
 for (int idx = startIdx; idx < startIdx+100; ++idx) {
  CString str;
  str.Format(_T("%d"), idx);
  g_ArrString.Add(str);
 }
 return 0;
}
 
void CThreadTestDlg::OnBnClickedBtn()
{
 for (int idx = 1; idx <= 50; ++idx) {
  AfxBeginThread(ThreadProc, (LPVOID)(idx*10));
 }
}
 
void CThreadTestDlg::OnBnClickedPrintBtn()
{
 CString strCount;
 INT_PTR nCount = g_ArrString.GetCount();
 strCount.Format(_T("%d"), nCount);
 MessageBox(strCount);
 
 for (INT_PTR idx = 0; idx < nCount; ++idx) {
  OutputDebugString(g_ArrString.GetAt(idx));
 }
}
===================================================
②、原子互锁家族函数:
1、InterlockedIncrement:加1操作;
2、InterlockedDecrement:减1操作;
3、InterlockedExchangeAdd:加上“指定”的值,可以加上一个负数;
4、InterlockedExchange、InterlockedExchangePointer:能够以原子操作的方式用第二个参数的值来取代第一个参数的值;
===================================================
其他互锁家族的函数大家也可以参考下MSDN,理解理解意思!
一般情况下,在多线程编程中如果对某一个变量的值进行改变的话,使用以上互锁函数确实比较方便,但有很多时候多线程间会操作更为复杂的东西
比如对一个结构的赋值、对链表的插入与删除 等等,以上互锁函数不能满足要求,所以要使用更为高级的多线程间的同步技术!
===================================================
③、Critical Sections(关键代码段、关键区域、临界区域)
 
使用方法:
1、初始化:InitializeCriticalSection;
2、删除:DeleteCriticalSection;
3、进入:EnterCriticalSection(可能造成阻塞);
4、尝试进入:TryEnterCriticalSection(不会造成阻塞);
5、离开:LeaveCriticalSection;
 
固有特点(优点+缺点):
1、是一个用户模式的对象,不是系统核心对象;
2、因为不是核心对象,所以执行速度快,有效率;
3、因为不是核心对象,所以不能跨进程使用;
4、可以多次“进入”,但必须多次“退出”;
5、最好不要同时进入或等待多个 Critical Sections,容易造成死锁;
6、无法检测到进入到 Critical Sections 里面的线程当前是否已经退出!
===================================================
※※※ 小作业:
MFC中同样对 Critical Sections 进行了封装,所以尝试使用 CCriticalSection 类进行线程间的同步将更为方便!
------------------------------------- End -------------------------------------------

vc++高级班之多线程篇[6]---线程间的同步机制①的更多相关文章

  1. vc++高级班之多线程篇[7]---线程间的同步机制②

    //示例代码: CStringArray g_ArrString; UINT __cdecl ThreadProc(LPVOID lpParameter) {  int startIdx = (int ...

  2. iOS开发多线程篇 04 —线程间的通信

    iOS开发多线程篇—线程间的通信 一.简单说明 线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信 线程间通信的体现 1个线程传递数据给另1个线程 在1个线程中执行完特定任 ...

  3. vc++高级班之窗口篇[4]---让程序只运行一个实例

      大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...

  4. Linux 多线程 - 线程异步与同步机制

    Linux 多线程 - 线程异步与同步机制 I. 同步机制 线程间的同步机制主要包括三个: 互斥锁:以排他的方式,防止共享资源被并发访问:互斥锁为二元变量, 状态为0-开锁.1-上锁;开锁必须由上锁的 ...

  5. iOS开发多线程篇—创建线程

    iOS开发多线程篇—创建线程 一.创建和启动线程简单说明 一个NSThread对象就代表一条线程 创建.启动线程 (1) NSThread *thread = [[NSThread alloc] in ...

  6. Java并发之线程间的同步协作与通信协作

    1,Monitor监视器与syncrhoized实现原理 1.1:Monitor Monitor是一个同步工具,相当于操作系统中的互斥量(mutex),即值为1的信号量. 它内置与每一个Object对 ...

  7. iOS开发多线程篇 03 —线程安全

    iOS开发多线程篇—线程安全 一.多线程的安全隐患 资源共享 1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源 比如多个线程访问同一个对象.同一个变量.同一个文件 当多个线程访问同一块 ...

  8. swift开发多线程篇 - NSThread 线程相关简单说明(一些使用和注意点)

    一 说明 本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得. 二 NSThread的基本使用和创建 1)基本用法(主线程|当前线程) 1 ...

  9. java多线程5:线程间的通信

    在多线程系统中,彼此之间的通信协作非常重要,下面来聊聊线程间通信的几种方式. wait/notify 想像一个场景,A.B两个线程操作一个共享List对象,A对List进行add操作,B线程等待Lis ...

随机推荐

  1. java io系列07之 FileInputStream和FileOutputStream

    本章介绍FileInputStream 和 FileOutputStream 转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_07.html File ...

  2. JAVA核心技术I---JAVA基础知识(单例模式和final关键字)

    一:单例模式 C++设计模式中提及,不再赘述设计模式---对象性能模式之单例模式(Singleton) public class single{ static single Instance=new ...

  3. logging 模块 与 logging 固定模块

    import logging # 1. 控制日志级别# 2. 控制日志格式# 3. 控制输出的目标为文件logging.basicConfig(filename='access.log', forma ...

  4. MySQL随记(二)

    第一范式(1NF First Normal Format): 1. 列具有原子性(atomic) 原子(atom)是物质的最小单元, 它不能被再分割为更小的元素. 2. 表具有主键(Primary K ...

  5. SQL Server进阶(十一)存储过程

    存储过程和函数的区别 存储过程是第一次编译之后就会被存储的下来的预编译对象,之后无论何时调用它都会去执行已经编译好的代码.而函数每次执行都需要编译一次.总结下来有下面几个区别: 基本不同: 函数必须有 ...

  6. extjs.net Combox赋值

    1.直接赋值 ].Rows) //遍历获取两个值 { Ext.Net.ListItem listItem = new Ext.Net.ListItem(); //每次创建一个Ext.Net.ListI ...

  7. 【U3d】场景加载-GameStart!

    目的:实现点击按钮场景切换 一共四个步骤,轻松食用(ง •̀_•́)ง 1. GameObject→UI→Button向开始场景中添加按钮,示例如下 2. 新建script——"LoadSc ...

  8. IDEA 远程调试 Tomcat 和 Debugger

    一般来说我们本地环境使用Tomcat,生产环境使用GlassFish. 准备工作 明确远程服务器的 IP 地址,比如:192.168.92.128 关掉服务器防火墙:service iptables ...

  9. mysql日期时间函数(常用的)

    mysql> SELECT NOW();  #返回(打印)当前日期和时间+---------------------+| NOW() |+---------------------+| 2017 ...

  10. Maven 那点事儿(转)

    0. 前言 Jason Van Zyl,在 Java 十大风云人物排行榜上或许会看到他. 这兄弟是干嘛的? 他就是 Maven 的创始人,人们都尊称他为“Maven 他爸”. 毋庸置疑,Jason 也 ...