设为首页 加入收藏

TOP

windows多线程编程星球(一)(一)
2017-10-11 18:24:43 】 浏览:734
Tags:windows 线程 编程 星球

         以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分。原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这部分内容主要出现在讲原理的操作系统书的某一章,看完原理是懂了,但是呢很难和编程实际结合起来,感觉很抽象,因为一般操作系统的书都没有啥代码。换到编程相关的书籍上面,讲语言的自然不会讲这个,讲编程技巧的也很难涉及到这一块。感觉就是这部分知识本来就不是很多,而且还散落在各个地方,想要原理实践都掌握有点收集七龙珠的感觉。这段时间工作正好接触这部分还挺多,遂觉得把我这一点点在编程上的领悟写出来,也许也有和当年一样需要的人。

         上面说了多线程这东西多是和操作系统有关的知识,但是毕竟我主要目的是想通过具体的程序来具体化这个原理,争取能做到能从实践的角度说明白原理,所以我选择了windows那一套线程函数来说明这一切,虽然windows下面的线程也有很多弊端,但是说起来个人感觉要简单点。为了不成为枯燥的windows函数说明文章,我尽力想了一个小的场景来说明这一切,希望能够让文字有点吸引力。

         为了不要文章太长,我决定分成两个部分,第一个部分从简单的开始,扯扯两个线程之间的二人世界,第二部分开始插入第三者,扯扯多个线程之间的复杂关系。

 

一、线程世界,星球与母星。

         为了说明进程,线程之间的关系,我决定把我的这个命令行程序命名为“MyThrWorld”,Thr是Thread的前三个字母,随着要介绍的内容,我会慢慢的介绍我脑子里这个世界的信息。说是世界,但是世界上元素不会超过10个,毕竟先起个霸气的名字比较重要!

         这个世界主要组成部分是“星球”,每个星球由以下几个主要属性:

struct Planet
{
    int type;   //星球类型
    int resource; //资源数目
    int speed; //行进速度
    int index; //编号
};
 

        这个世界的创造者是一个母星,home planet,我把它初始化成这样。初始化的顺序和上面struct的顺序相同,用1代表母星类型,我是有点懒,最好是定义一个常量,这样可读性更强一些:

struct Planet homePlanet = InitPlanet(1,nMaxResource,0,0); 

 

       nMaxResoure是整个输出的DOS窗口的最大宽度,这个的目的是为下面的程序里面画的图不要找不到去哪了,如何取得windows console的输出DOS窗口的最大宽度以及和这个窗口相关的更多信息呢?请搜索console api windows,在这里毕竟这不是重点,我们使用全局变量hout来标识输出的dos console窗口:

HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);

CONSOLE_SCREEN_BUFFER_INFO bInfo; 
GetConsoleScreenBufferInfo(hOut, &bInfo );

nMaxResource = bInfo.dwSize.X;

     假设这个home planet是这个世界的创造者,他的作用是分离出新的星球或者链接新的星球。 母星目前唯一的运动是旋转,我设计了一个十分简单的旋转逻辑,主要代码如下:

void PlanetSpin(const struct Planet &p,int spinInterval,int picType)
{
    char spin[4] = {'|','/','-','\\'}; 

    if( p.type == 1 )
    {   
        MoveOutputToPos(0,0,&spin[picType%4],false); 
        MoveOutputToPos(0,1,&spin[picType%4],false); 
        MoveOutputToPos(1,0,&spin[picType%4],false); 
        MoveOutputToPos(1,1,&spin[picType%4],false);
 
        ::Sleep(spinInterval);
    }
    else
    { 
        ...
    }
}
 

      else部分的代码后面再说明,大体意思就是让一个planet以某一个间隔旋转(spinInterval),其实也就是刷新时间,其中我把所有和在dos窗口中指定地点输出指定图形的内容分离出来用一个单独的函数,因为这部分在后面使用的还是挺频繁的并且会让我们遇到多线程编程的第一个重要知识点。MoveOutputToPos前两个参数是DOS窗口的横坐标和纵坐标,第三个是输出的字符,最后一个是为了后面输出string准备的,第一版代码大体是下面这个样子的,用到的还是console api。

void MoveOutputToPos(int x,int y,char* c,bool bString)
{     
    csbiInfo.dwCursorPosition.X = x;
    csbiInfo.dwCursorPosition.Y = y; 

    if (!SetConsoleCursorPosition(hOut,csbiInfo.dwCursorPosition)) 
    {
        printf("SetConsoleCursorPosition error!!!!! \r\n"); 
        return;
    }

    if(!bString)
        printf("%c",c[0]); 
    else
        printf("%s",c);
}

    

二、分离星球。

       母星的第一个作用是分离出子星球,既然是子星球这么直白朴实的名字,我相信你也猜到了,我就是用这个表示子线程。一个子星球在线程世界里面就是一个独立的,但是又和母星有关联的个体,这也符合线程的基本特点。同样子星球也有资源属性并且都和母星球共用一个资源库,而且也会旋转。但是毕竟他不完全是母星球,还是有一点不同的,子星球可以前进。既然文章主要是介绍多线程,那么我们就从创建一个子星球来开始第一个多线程相关的函数。

HANDLE  hThread1 = CreateThread(0,      //
首页 上一页 1 2 3 4 5 6 下一页 尾页 1/6/6
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇win7如何恢复以前的ie版本 下一篇在IE中解决当前安全设置不允许下..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目