使用kbhit()和getch()和“状态标志位”退出多线程

前言
在我们平时控制台程序的编写过程中,使用多线程, 如: 子线程中执行任务, 主线程线程中检测用户输入, 然后根据用户输入, 来控制工作线程状态;
如果仅仅是快速做测试, 可以使用C语言中的kbhit()和getch()来实现上述功能.
个人理解: kbhit()内部也是封装了一个线程来检测用户键盘输入.

本示例使用标志位 flag 控制另一个线程的停止。

示例:

#include <iostream>
#include <thread>
#include <Windows.h>
#include <conio.h>  // _kbhit(), _getch()

using namespace std;
extern int flag = 1;

void rec_cmd() {
	int counter = 0;
	char exitflag = '\0';
	while (1)
	{
		Sleep(50);

		//函数名:kbhit()
		//功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
		if (_kbhit())
		{
			// 函数名: getch()
			// 功能及返回值: 从键盘上读取到的字符
			exitflag = _getch();
			if (exitflag == 'q' || exitflag == 'Q')
			{
				std::cout << "用户输入:" << exitflag << ", 退出循环\n";
				flag = 0;
				break;
			}
		}
	}
	std::cout << "已经退出了循环\n";
}

void print_test() {
	while (flag) {
		Sleep(1000);
		cout << "print test is ok ."<<endl;
	}
	
}
int main()
{
	thread t1(rec_cmd);
	thread t2(print_test);
	t1.join();
	t2.join();
	return 0;
}

控制台输出
控制台输出
另附用 c11 封装的线程安全队列

#pragma once
#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <queue>
 
template <class T>
class Queue {
protected:
	// Data
	std::queue<T> _queue;
	typename std::queue<T>::size_type _size_max;
 
	// Thread gubbins
	std::mutex _mutex;
	std::condition_variable _fullQue;
	std::condition_variable _empty;
 
	// Exit
	// 原子操作
	std::atomic_bool _quit; //{ false };
	std::atomic_bool _finished; // { false };
 
public:
	Queue(const size_t size_max) :_size_max(size_max) {
		_quit = ATOMIC_VAR_INIT(false);
		_finished = ATOMIC_VAR_INIT(false);
	}
 
	bool push(T& data)
	{
		std::unique_lock<std::mutex> lock(_mutex);
		while (!_quit && !_finished)
		{
			if (_queue.size() < _size_max)
			{
				_queue.push(std::move(data));
				//_queue.push(data);
				_empty.notify_all();
				return true;
			}
			else
			{
				// wait的时候自动释放锁,如果wait到了会获取锁
				_fullQue.wait(lock);
			}
		}
 
		return false;
	}
 
 
	bool pop(T &data)
	{
		std::unique_lock<std::mutex> lock(_mutex);
		while (!_quit)
		{
			if (!_queue.empty())
			{
				//data = std::move(_queue.front());
				data = _queue.front();
				_queue.pop();
 
				_fullQue.notify_all();
				return true;
			}
			else if (_queue.empty() && _finished)
			{
				return false;
			}
			else
			{
				_empty.wait(lock);
			}
		}
		return false;
	}
 
	// The queue has finished accepting input
	void finished()
	{
		_finished = true;
		_empty.notify_all();
	}
 
	void quit()
	{
		_quit = true;
		_empty.notify_all();
		_fullQue.notify_all();
	}
 
	int length()
	{
		return static_cast<int>(_queue.size());
	}
};

小白 如有错误,欢迎提出,谢谢!
另附多线程学习资料:秒杀多线程第一篇 多线程笔试面试题汇总 - MoreWindows Blog - CSDN博客
参考文献:
1.使用kbhit()和getch()无阻塞接收用户键盘输入 - liuhhaiffeng的专栏 - CSDN博客
2.基于std::queue C++11 线程安全队列。 - fengchu3415的博客 - CSDN博客

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
01-13 2701
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值