计时器与多线程(无聊应试向)

Posted 临风而眠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计时器与多线程(无聊应试向)相关的知识,希望对你有一定的参考价值。

计时器与多线程总结(无聊应试向)


​ C++要结课考试了 😟,接下来会写一系列无聊的应试向blog😕,在复习的时候顺便写写blog,不过也会力求一些趣味性😉

一.preparation

​ 后面的程序我都要调用一个自建文件,大家可以自己起个名,我命名为“base.cpp"(#include"base.cpp",记得在用”base.cpp"的时候把base.cpp和你的程序文件放在一个文件夹里面)

//光标移动到指定坐标处
void gotoxy(int x,int y)
{
	HANDLE h;//句柄,对象的索引
	COORD c;//结构体,坐标值
	c.X=x;
	c.Y=y;
	h=GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(h,c);
}

//隐藏光标
void hide_cursor()
{
	HANDLE	h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor_info;
	GetConsoleCursorInfo(h_GAME,&cursor_info); 
	cursor_info.bVisible=false;					//不显示光标
	SetConsoleCursorInfo(h_GAME,&cursor_info); 
}

//显示光标
void show_cursor()				
{
	HANDLE	h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursor_info;
	GetConsoleCursorInfo(h_GAME,&cursor_info); 
	cursor_info.bVisible=true;					//显示光标
	SetConsoleCursorInfo(h_GAME,&cursor_info); 
}

//设置文本颜色
void color(int a)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),a);
}


二.计时器

1.单线程

①显示一个计时器

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<cstdlib>
#include<ctime>
#include <iomanip>//格式化输出头文件
#include"base.cpp"

using namespace std;
class timing
{
private:

    int time_print;//要在屏幕上显示的事件

    clock_t time_update;//记录实时时间的变量
public:
    timing()
    {
        time_print=0;
        time_update=clock();//开始计时了
        hide_cursor();//隐藏光标
    }
    void move_clock()
    {

        if(clock()-time_update>2000)
        {
            gotoxy(10,10);
            ++time_print;
            cout<<setw(3)<<setfill('0')<<time_print;
            time_update=clock();//重新记录当下时间
        }
    }
    void General()//总线程
    {
        while(true)
        {

            move_clock();
        }

    }
    ~timing()
    {
        show_cursor();
    }

};
int main()
{

    timing t;
    t.General();
    return 0;
}

②长脚的钟表

#include<iostream>
#include<windows.h>
#include<conio.h>
#include<cstdlib>
#include<ctime>
#include <iomanip>//格式化输出头文件
#include"base.cpp"

using namespace std;
class timing
{
private:

    int time_print;//要在屏幕上显示的事件
    int x,y;
    clock_t time_update;//记录实时时间的变量
public:
    timing()
    {
        time_print=0;
        time_update=clock();//开始计时了
        hide_cursor();//隐藏光标
        x=1;
        y=1;
    }
    void move_clock()
    {

        if(clock()-time_update>2000)
        {   gotoxy(x,y);
            cout<<"   ";//先把原先那个地方的清除掉


            ++time_print;
            ++x;
            ++y;
            gotoxy(x,y);
            cout<<setw(3)<<setfill('0')<<time_print;
            time_update=clock();//重新记录当下时间
        }
    }
    void General()//总线程
    {
        while(true)
        {

            move_clock();
        }

    }
    ~timing()
    {
        show_cursor();
    }

};
int main()
{

    timing t;
    t.General();
    return 0;
}

2.多线程

①用键盘让你的计时器满地图跑

此处两个线程,一个是计时器,一个是键盘交互

//秒表计时器-多线程(键盘控制)
#include <windows.h>
#include <iostream>
#include <ctime>
#include <list>
#include <iomanip>
#include "base.cpp"
using namespace std;

class timing
{
private:
    clock_t time_update1;//计时器输出的线程
    clock_t time_update2;//键盘控制的线程
    int x,y;//坐标
    int time_print;//输出的时间
public:
    timing()
    {
        x=0,y=0;//坐标初始化
        time_update1=clock();
        time_update2=clock();
        hide_cursor();

    }

    void move_clock()
    {
        if(clock()-time_update1>1000)
        {

            draw();
            ++time_print;
            time_update1=clock();
        }

    }
    void move_keyboard()
    {
        if(clock()-time_update2>50)//这里的时间决定了灵敏度
        {
            Erase();
            if(GetAsyncKeyState(VK_ESCAPE))exit(0);
            if(GetAsyncKeyState(VK_UP))--y;//注意坐标系y往上坐标变小
            if(GetAsyncKeyState(VK_DOWN))++y;
            if(GetAsyncKeyState(VK_RIGHT))++x;
            if(GetAsyncKeyState(VK_LEFT))--x;
            draw();
            time_update2=clock();
		//注意先擦除再绘制的基本逻辑
        }
    }
    void draw()
    {
        gotoxy(x,y);
        cout<<setw(3)<<setfill('0')<<time_print;//格式化输出
    }
    void Erase()
    {
        gotoxy(x,y);
        cout<<"   ";

    }
    void General()
    {
        while(true)
        {
            move_clock();
            move_keyboard();
        }
    }
    ~timing()
    {
        show_cursor();
    }
};

int main()
{
    timing t;
    t.General();
    return 0;
}

②逻辑(流程图显示)

Created with Raphaël 2.2.0 ... 计时器1 线程1 计时器2 线程2 ... yes no yes no
//这个流程图是typora内置的flowchart语法画的,我画的有点难看┭┮﹏┭┮
//现在发现了一个在线画图神器process on,里面的flowchart流程图可以直接拖拽
//以后我就在那里截图配合我的Picgo图床,真香!

三.examples

1.逐步完善一个滚动的小球

①让小球自己从下向上运动,实现边界检测

//自主运动的小球
#include <windows.h>
#include <iostream>
#include <ctime>
#include <list>
#include <iomanip>
#include "base.cpp"
using namespace std;

class ball
{
private:
    int x,y;//坐标
    clock_t time_update;
public:
    ball()
    {
        x=39;
        y=12;//先让小球显示在屏幕中央
        time_update=clock();
        hide_cursor();
    }
    void draw()
    {
      gotoxy(x,y);
      cout<<"●";

    }
    void Erase()
    {
        gotoxy(x,y);
        cout<<"  ";//小球占两个字符,要cout两个空格

    }
    void move_clock()
    {
        if(clock()-time_update>100)//调这个数字可以控制小球的速度
        {
            Erase();
            --y;
            if(y<0)
            {
                y=12;
            }
            draw();
            time_update=clock();//更新计时器一定不能忘! 否则看到的就是不断闪现的老电视!
        }

    }
    void General()
    {
        while(true)
        {

            move_clock();
        }
    }
    ~ball()
    {
        show_cursor();
    }
};
int main()
{
    ball B1;
    B1.General();
    return 0;
}

要注意先擦除后绘制的逻辑!!!

可以多设几个变量实现自由落体的噢!😀

手残党弱弱提示class 后面的类后面不要加括号,这个习惯老改不掉😩

②实现键盘控制

//自主运动的小球
#include <windows.h>
#include <iostream>
#include <ctime>
#include <list>
#include <iomanip>

#include "base.cpp"
using namespace std;

class ball
{
private:
    int x,y;//坐标
    int choice;
    clock_t time_update1;
    clock_t time_update2;//第二个线程
public:
    ball()
    {
        x=39;
        y=12;//先让小球显示在屏幕中央
        time_update1=clock();
        time_update2=clock();
        hide_cursor();
    }
    void draw()
    {
      gotoxy(x,y);
      cout<<"●";

    }
    void Erase()
    {
        gotoxy(x,y);
        cout<<"  ";//小球占两个字符,要cout两个空格

    }
    void move_clock()
    {
        if(clock()-time_update1>200)//调这个数字可以控制小球的速度
        {
            Erase();
            switch(choice)
            {

                case 1:--y;if(y<0)y=24;break;
                case 2:++y;if(y>24)y=0;break;
                case 3:--x;if(x<0)x=78;break;
                case 4:++x;if(x>78)x=0;break;
            }
            draw();
            time_update1=clock();//更新计时器一定不能忘! 否则看到的就是不断闪现的老电视!
        }

    }
    void move_keyboard()
    {
        if(clock()-time_update2>200)
        {
            if(GetAsyncKeyState(VK_ESCAPE))exit(0);
            if(GetAsyncKeyState(VK_UP))choice=1;
            if(GetAsyncKeyState(VK_DOWN))choice=2;
            if(GetAsyncKeyState(VK_LEFT))choice=3;
            if(GetAsyncKeyState(VK_RIGHT))choice=4;
            time_update2=clock();
        }
    }
    void General()
    {
        while(true)
        {

            move_clock();
            move_keyboard();
        }
    }
    ~ball()
    {
        show_cursor()八.多进程与多线程

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

iOS runloop与多线程

winform中多线程与定时器冲突

winform中多线程与定时器冲突

C中的多线程与多处理