c语言线程wait函数,Qt 控制线程的顺序执行(使用QWaitCondition,并且线程类的run函数里记得加exec(),使得线程常驻)...

本文介绍如何使用QWaitCondition和信号槽机制在C++中实现线程的有序执行,通过创建input、process和output子类,利用条件变量和互斥锁控制线程流程,确保ABC顺序工作。关键步骤包括设置条件变量、线程工作函数的实现和信号与槽的关联。
摘要由CSDN通过智能技术生成

背景

项目中用到多线程,对线程的执行顺序有要求:

A.一个线程先收数据

B.一个线程处理数据

C.一个线程再将处理后的数据发送出去

要求三个线程按照ABC的顺序循环执行。

思路

子类化多线程方法

重写子类的run函数,在run函数内用while(1)来常驻线程,循环体内通过检查全局变量来判断是否到自己执行,不是自己线程则跳过,是自己线程执行完后改变全局标志位。通过全局标志位来控制线程的执行顺序。所以需要一个全局变量来标记当前应当执行的线程,同时用一个互斥量来保护该全局变量。

movetoThread多线程方法

为每个线程设计相应的方法类,将生成的方法类对象移入到对应的线程内,方法类的方法必须通过信号和槽的方式来触发。

本文采用第二种思路来实现线程的顺序执行

QWaitConditon简介

线程如何睡眠?

调用QWaitCondition的wait函数将使得调用它的线程进入睡眠状态

线程如何醒来?

在另外的线程中调用QWaitConditon的wakeOne或者wakeAll方法将唤醒等待它的线程

实现过程

先定义全局变量

QWaitCondition condition_input; //数据收线程的条件变量,控制线程睡眠和唤醒

QWaitCondition condition_process;//数据处理线程的条件变量,控制线程睡眠和唤醒

QWaitCondition condition_output;//数据发线程的条件变量,控制线程睡眠和唤醒

//保护条件变量,防止多线程同时访问条件变量

QMutex mutex_input;

QMutex mutex_process;

QMutex mutex_output;

1

2

3

4

5

6

7

8

2.实现接收数据的方法的槽函数

void input::work()

{

while(1)//使得线程常驻

{

qDebug()<

mutex_process.lock();

condition_process.wakeOne();//唤醒下一次的数据处理线程

mutex_process.unlock();

mutex_input.lock();

condition_input.wait(&mutex_input);//睡眠当前的收线程

mutex_input.unlock();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

3.实现处理数据的方法的槽函数

void process::work()

{

while (1)

{

qDebug()<

mutex_output.lock();

condition_output.wakeOne();//唤醒下一次的发线程

mutex_output.unlock();

mutex_process.lock();

condition_process.wait(&mutex_process);//睡眠当前处理线程

mutex_process.unlock();

}

}

void process::threadSleep()

{

qDebug()<<:currentthreadid>

mutex_process.lock();

condition_process.wait(&mutex_process);//睡眠当前处理线程

mutex_process.unlock();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

4.实现发送数据的方法的槽函数

void output::work()

{

while (1)

{

qDebug()<

mutex_input.lock();

condition_input.wakeOne();//唤醒下一次的收线程

mutex_input.unlock();

mutex_output.lock();

condition_output.wait(&mutex_output);//睡眠当前的发线程

mutex_output.unlock();

}

}

void output::threadSleep()

{

qDebug()<<:currentthreadid>

mutex_output.lock();

condition_output.wait(&mutex_output);//睡眠当前的发线程

mutex_output.unlock();

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

5.main函数中的最终实现

input_thread = new inputThread();

process_thread = new processThread();

out_thread = new outputThread();

//开启线程

input_thread ->start();

process_thread ->start();

out_thread ->start();

//生成方法对象

data_input = new input();

data_process = new process();

data_output = new output();

//移入线程

data_input->moveToThread(input_thread);

data_process->moveToThread(process_thread);

data_output->moveToThread(out_thread);

//使得数据处理和数据发送线程睡眠的槽函数和按键1的点击信号关联

connect(this,SIGNAL(click1()),data_process,SLOT(threadSleep()));

connect(this,SIGNAL(click1()),data_output,SLOT(threadSleep()));

//使得三个线程的work槽函数和按键1的点击信号关联

connect(this,SIGNAL(click2()),data_input,SLOT(work()));

connect(this,SIGNAL(click2()),data_process,SLOT(work()));

connect(this,SIGNAL(click2()),data_output,SLOT(work()));

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

使用方法

先触发click1信号,使得数据处理线程和数据发送线程睡眠;再触发click2信号,使得三个线程按照既定的顺序ABC循环执行。

输出结果

input1

process2

output3

input1

process2

output3

input1

process2

output3

input1

process2

output3

1

2

3

4

5

6

7

8

9

10

11

12

注意事项

线程类的run函数里记得加exec(),使得线程常驻

---------------------

作者:蜗牛在听雨

来源:CSDN

原文:https://blog.csdn.net/omg_orange/article/details/82388243

版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值