ASP源码.NET源码PHP源码JSP源码JAVA源码DELPHI源码PB源码VC源码VB源码Android源码
当前位置:首页 >> 操作系统 >> Windows 7jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播 >> windows多线程编程 windows多线程编程星球(一)

windows多线程编程 windows多线程编程星球(一)(3/8)

来源:网络整理     时间:2016-07-12     关键词:windows多线程编程

本篇文章主要介绍了"windows多线程编程 windows多线程编程星球(一)",主要涉及到windows多线程编程方面的内容,对于Windows 7jrs看球网直播吧_低调看直播体育app软件下载_低调看体育直播感兴趣的同学可以参考一下: 以前在学校的时候,多线程这一部分是属于那种充满好奇但是又感觉很难掌握的部分。原因嘛我觉得是这玩意儿和编程语言无关,主要和操作系统的有关,所以这...

       【更多】这里我最想讨论的是CreateThread里面的第二个参数,以及线程id和线程handle的区别。 CreateThread的第二个参数表示给线程分配的起始堆栈大小,这个大小是耗用进程的虚拟内存空间的,在PC系统上一个进程的虚拟内存空间大小至少都是4G,所以大多数时候这个参数所造成的影响基本真的是没有。而我经常碰到的嵌入式平台,一个进程的虚拟内存地址有的时候非常的小,比如wince5只有32mb(虽然系统是老的不能再老了,但是还是有用),如果一旦不小心几个线程的这个参数值没有注意,很容易一起来就挂了。而一个线程除了起始堆栈大小,还有reserved堆栈大小,你可以理解为reserved的堆栈大小是一个用来保护作用的线程最大能够使用的堆栈大小,这个reserved的默认值一般是设置在exe的头部的,默认值一般是1MB。那么如果你第二个参数设置的大于1MB会怎么样呢,这样系统会默认增长reserved的内存大小到离起始大小最近的1MB。 特别注意的是如果在倒数第二个参数中使用STACK_SIZE_PARAM_IS_A_RESERVATION,那么你就可以设置这个reserved的堆栈大小,这个时候,起始堆栈大小就是exe程序头中的一个默认值。另外值得特别注意的是,线程的堆栈空间只有在线程自己退出的情况下才会被释放,如果这个线程是被其他线程终止的,那么这部分堆栈空间将不会被释放。忘了说了,终止线程的函数是TerminateThread,只需要一个线程的handle,和一个exit code作为参数就可以。说到handle和线程id的区别,简单的说可以认为handle是我们写程序所使用的线程标识符而id是一个用户可读的线程标识符。

三、不友好的显示。

         如果你使用上面的逻辑以及代码去运行一下这个程序,试图查看一下运行起来到底是什么样子的。我可以大胆预测你第一次运行看到的和你脑海里想的完全不一样,那你要说了,难道第二次就一样了吗?答案是还是不一样,第三次到第n次都和你想象的不一样并且很可能这n次相互之间也完全不一样。一种满屏的杂乱感,你会发现本有些该在指定位置输出的符号并没有输出,而是在另外一个风马牛不相及的地方输出了。调试一下吧,你会发现特别的不顺,甚至每一次运行结果行为都不一样。这就是多线程编程的一个特点和难点,难以调试并且预测,所以我们就需要对这种杂乱无章的行为进行约束和控制。

        首先,分析一下为何会出现这样的行为,我们的函数不多,可以用注释一部分的办法来试试看看能不能找到问题在哪里。第一步,首先把createthread注释掉,或者倒数第二个参数使用CREATE_SUSPENDED,这样线程会被挂起,并不会被执行。你会发现,在只有一个主线程的情况下,一切运行如你所料,说明创建一个线程确实会导致不友好的显示问题。按照这个思路,接下来我们应该到线程函数threadproc里面找一找原因,一共也就俩函数,想到是显示出了问题,所以最大的怀疑对象是在函数MoveOutputToPos上面,既然这样,我们把move和spin里面MoveOutputToPos函数注释掉再试试,发现也没有问题。那么可以把注意点放在这个函数里面了。这个函数主要由两个部分组成,SetConsoleCursorPosition和printf,另外还有一个给CONSOLE_SCREEN_BUFFER_INFO变量赋值。为了一探究竟到底发生了啥,我们是稍微临时改造一下这个函数,传入星球的类型,这样我们就可以做一些输出了。第一步,现在变量CONSOLE_SCREEN_BUFFER_INFO赋值后面加入printf(“%d->x:%d,y:%d\r\n”,type,csbiInfo.dwCursorPosition.X ,csbiInfo.dwCursorPosition.Y)。运行一下你会发现,这个基本没有什么错误,坐标值对于每个类型基本都是你传入的都是正确的,那么为什么感觉设置的输出位置总是不对呢?只能把目光放在SetConsoleCursorPosition另外一个参数handle hout上面了,这个参数是是一个全局变量,那么从代码的角度出发也就是说作用域是整个代码文件,也就是说不管是main还是threadproc都是使用的这一个值,而在调用SetConsoleCursorPosition时,就可能发生主线程调用的这个函数但是下一秒切换成子线程的hout拷贝到寄存器上,造成了混乱。这就是多线程编程中的一个永恒而又核心的问题,资源的竞争。

windows多线程编程相关图片

windows多线程编程相关文章