1.同步线程:何为同步?

参考百度百科:

1.1 线程

线程是进程中的一个实体,是被系统独立调度和分配的基本单位。一个进程可以有多个线程,一个线程必须有一个父进程,线程自己不拥有系统资源,只有运行必须的一些数据结构,但它可以与同属一个进程的其他线程共享进程所拥有的全部资源,一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。

1.2 多线程

由于线程之间的相互制约,致使线程在运行中呈现出间断性,线程也有就绪、阻塞、和运行3种基本状态,所以,在一个进程中可以创建几个线程来提高程序的执行效率,并且有些程序还通过采用多线程技术来同事执行多个不同的代码模块。 
在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步

1.3 线程同步

即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,目前实现线程同步的方法有很多,临界区对象就是其中一种。
临界区的使用步骤:
1.初始化一个CURITY_ATTRIBUTES结构,在临界区对象之前,需要定于全局CURITY_ATTRIBUTES结构变量,在调用CreateThread函数前调用InitializeCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函数初始化临界区对象。 
2.申请进入一个临界区。在线程函数中要对保护的数据进行操作前,可以通过调用 EnterCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函数申请进入临界区,由于在同一时间内,只允许一个线程进入临界区,所以在申请的时候如果有一个线程进入到临界区,则该函数就会一直等到那个线程执行完临界区代码。 
3.离开临界区。当执行完临界区代码后,需要调用LeaveCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函数把临界区交还给系统。 
4.删除临界区,当不需要临界区是可以调用DeleteCriticalSection(LPC RITICAL_SECTION lpCriticalSection)函数将临界区对象删除。

1.4 怎么理解同步?

同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。“同”字从字面上容易理解为一起动作其实不是,“同”字应是指协同、协助、互相配合。如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回,同时其它线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。例如Window API函数SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。
在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。

2.线程等待条件

应用程序运行多线程时,无法保证哪个线程先运行,等待条件就等于同步线程。
例如,假如应用程序中有两个线程同时运行。第一个线程进行工作,第二个线程则处于待机状态,直到第一个线程完成到一定程度立即调用第二个线程,第二个线程才会开始工作。很明显这就是协同~
使用等待条件可以实现上述线程间的同步。为了使用等待条件,Qt提供了QWaitCondition类。QWaitCondition类使用函数wait()使线程进入阻塞状态,使用waitOne()或waitAll()则可以讲线程从阻塞状态唤醒。
需要注意的是,QWaitCondition在线程中与互斥体一起使用。
#include <QtWidgets/QApplication>
#include <QWaitCondition>
#include <QMutex>
#include <QThread>QMutex mutex;              //各线程的全局量
QWaitCondition incNumber;  //各线程的全局量
int numUsed;               //producer 和 consumer 的共享变量class Producer : public QThread
{
public:Producer() {}
protected:void run(){for(int i = 0 ; i < 10 ; i++){//sleep(1);mutex.lock();  //注意此互斥量生产者与消费者共享++numUsed;incNumber.wakeAll();qDebug("Producer-numUsed : %d", numUsed);mutex.unlock();}}
};class Consumer : public QThread
{
public:Consumer(){}
protected:void run(){for(int i = 0 ; i < 10 ; i++){mutex.lock();//incNumber.wait(&mutex);  //此处mutex与生产者是同一个,所以会等待生产者线程qDebug("Consumer-numUsed : %d", numUsed);mutex.unlock();        }}
};int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);Producer producer;Consumer consumer;producer.start();consumer.start();return a.exec();
}
  • //Sleep(1);//incNumber.wait(&mutex); 输出结果:
生产者消费者线程同时处于激活状态。尽在互斥量作用下交替抢占资源。
  • sleep(1); //incNumber.wait(&mutex);输出结果:

Producer::run()函数被sleep(1)拖延,所以,在拖延期间,线程Comsumer::run()抢占资源,直至完成操作。
  • sleep(1); incNumber.wait(&mutex);输出结果:

这个和第一个结果相同,但是执行原理却不同。第一个实验是线程Producer和线程Comsumer交替抢占资源。而该实验实现的是线程等待条件。
线程Producer比较耗时(空循环),线程Consumer内加入线程继续执行的等待条件。该过程可以描述为:
等待2s->Producer1->Consumer1...(暂时猜测等待超时,会强制执行)
调试代码:
        for(int i = 0 ; i < 10 ; i++){sleep(3);mutex.lock();  //注意此互斥量生产者与消费者共享++numUsed;incNumber.wakeAll();qDebug("Producer-numUsed : %d", numUsed);mutex.unlock();
       mutex.lock();incNumber.wait(&mutex);  //此处mutex与生产者是同一个,所以会等待生产者线程sleep(1);qDebug("Consumer-numUsed : %d", numUsed);mutex.unlock();        }
  • //sleep(1);  incNumber.wait(&mutex);输出结果:

该实验与实验三是一个对比实验。在没有延时情况下,不会启动强行执行。所以执行流程应该为:

Producer1->Producer1(customer唤醒但执行等待)->Customer1(等待结束,执行局部域)......

Qt修炼手册12_线程同步与线程等待条件相关推荐

  1. python 测试 多线程 _thread和threading模块 线程同步,线程优先级队列

    文章目录 python 多线程简介 Python中使用线程的两种方式 1.函数式 示例 2.线程模块 示例 线程同步 示例 线程优先级队列( Queue)[暂时没用到,没仔细看] 示例 其他 thre ...

  2. python中线程同步_Python线程同步在实际应用中功能体现

    在Python编程语言中,对于线程的操作是一个比较重要的应用技术.我们将会在这篇文章中为大家详细介绍一下这方面的相关基础内容,Python线程同步的应用方式.多个执行线程经常要共享数据,如果仅仅读取共 ...

  3. iOS开发——高级篇——线程同步、线程依赖、线程组

    前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...

  4. 什么是线程同步和线程异步?

    1.什么是线程同步和线程异步 线程同步:是多个线程同时访问同一资源,等待资源访问结束,浪费时间,效率不高 线程异步:访问资源时,如果有空闲时间,则可在空闲等待同时访问其他资源,实现多线程机制 异步处理 ...

  5. 多线程——线程实现、线程状态、线程同步、线程通信、线程池

    多线程 一.线程 1.普通方法调用和多线程 2.程序.进行.线程 二.线程创建 1.继承Thread类 2.实现Runable接口 3.实现Callable接口 4.静态代理模式 5.Lamda表达式 ...

  6. python 线程同步_Python 线程同步

    zhoushixiong Python 线程同步 以下代码可以直观展示加锁和不加锁时,对数据修改情况. 加锁时 # -*-* encoding:UTF-8 -*- # author : shoushi ...

  7. educoder 使用线程锁(lock)实现线程同步_线程间的通信(一)

    这篇文章主要从4个角度来讲多线程间的通信: 使用wait/notify实现线程间的通信 生产者/消费者模式的实现 方法join的使用 ThreadLocal类的使用 等待/通知机制的实现: (1)wa ...

  8. 线程同步(互斥锁、条件、读写锁、信号量)

    参考:(四十三)线程--线程同步(互斥锁.读写锁.条件变量.信号量) 作者:FadeFarAway 发布时间:2017-01-17 21:25:28 网址:https://blog.csdn.net/ ...

  9. Thread 线程同步、线程状态

    线程概念 线程(英语:thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位. 一.多线程介绍 1.1创建线程类 Java中通过继承Thread类来创建并启动多 ...

最新文章

  1. PCL点云配准(1)
  2. 【Deep Clustering】Improving Unsupervised Image Clustering With Robust Learning
  3. 01-迭代开发的基本需求和Scrum标准
  4. VigiBase中搜索和眼病相关的统计数据
  5. 多所“双一流”明确将扩招!清华、上交、哈工大等也做出回应
  6. (3~4):C实现数组选择排序
  7. Pandas基础(一)——Pandas基础
  8. python求解LeetCode习题Maximum Gap
  9. 经典的CSS代码(转)
  10. python对excel读写操作
  11. SpringBoot中配置文件dev、test、和prod各自代表什么意思?
  12. Python轻松多条件计数与求和
  13. 腾讯qq的授权管理查看页面
  14. 次梯度(subgradient)方法
  15. 2017-07-06:大神
  16. 《漫步华尔街》 读书笔记 part1 历史
  17. Keras深度学习实战(35)——构建机器翻译模型
  18. GitLab合并请求时出现 Validate branchesCannot Create: This merge request already existed
  19. 软件实习项目2——贪吃喵(猫吃鱼版贪吃蛇)(实验准备与设计)
  20. 禾木生物冲刺港股:9个月亏3亿 高瓴与三正健康是股东

热门文章

  1. 利用python自带的包可以建立简单的web服务器
  2. Struts2 自定义拦截器(方法拦截器)
  3. 保定linux第一版PPT-SVN for Linux
  4. LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)
  5. 将web项目导入到eclipse/MyEclipse中常见错误
  6. NYOJ 76 超级台阶
  7. java 中方法重载
  8. Java开发知识之Java中的集合上List接口以及子类讲解.
  9. 【Java】 大话数据结构(13) 查找算法(4) (散列表(哈希表))
  10. Sublime Text 3快捷键汇总