Yesky首页| 产品报价| 行情| 手机 | 数码 | 笔记本 | 台式机 | DIY硬件 | 外设 | 网络 | 数字家庭 | 评测 | 软件 | e时代 | 游戏 | 图片 | 壁纸 | 群乐 | 社区 | 博客 | 下载
您现在的位置: 天极网 > 开发频道 > Win32程序设计初步之线程
全文

Win32程序设计初步之线程

2004-11-05 00:04 作者: QQ新人类编译 出处: 天极网 责任编辑:方舟
  例子1

  对于许多人来说,要从一个单一的进程中创建多个线程的话,在观念上就要做一些改变。我们首先来看几个非常简单的例子,了解一下Win32 API中线程的基本运作是怎样的。

  以下的代码是一个非常简单的单线程程序。在这个程序中,用户每按下回车键一次,就会输出全局变量count的值。由于在程序中并没有改变count的值,因此该程序一直输出0。这里并没有使用什么技巧:

#include
#include

UINT count;

void main(void)
{
 CHAR retStr[100];

 count=0;
 while(1)
 {
  cout << "Press to display the count... ";
  cin.getline(retStr, 100);
  cout << "The count is: " << count << endl
  << endl;
 }
}

  现在要为这些代码增加一个线程。NT中的线程其实就是后台中执行的一个函数。代码中的CountThread函数增加全局变量count的值,然后休眠100毫秒。在你运行程序的时候,你将会发现每次按下回车键,count的值就会增加。后台中的线程也会增加count的值,同时以前的线程也会响应用户的输入。这个程序会同时做两件事情。

#include
#include

volatile UINT count;

void CountThread()
{
 while(1)
 {
  count++;
  Sleep(100);
 }
}

void main(void)
{
 HANDLE countHandle;
 DWORD threadID;
 CHAR retStr[100];

 count=0;

 // create a thread which
 // executes the "CountThread" function
 countHandle=CreateThread(0, 0,(LPTHREAD_START_ROUTINE) CountThread,0, 0, &threadID);
 if (countHandle==0)
  cout << "Cannot create thread: "
  << GetLastError() << endl;

  while(1)
  {
   cout<< "Press to display the count... ";
   cin.getline(retStr, 100);
   cout << "The count is: " << count << endl
   << endl;
  }
}

主线程、后台线程和全局变量之间的关系可用下图表示:



****************图一********************

以上通过使用CreateThread函数来创建线程(该函数的具体描述可参考VC++ 2.0版本的Win32在线帮助或者NT的SDK文档)。CreateThread接受线程函数的名字,该函数会在新的线程中执行。这里的线程函数就是CountThread。线程函数可以选择接受一个4字节的参数。在上面的代码中,线程函数并没有使用任何的参数,不过如果有的话这些参数将会被传送至CreateThread的参数列表中,并且CreateThread会把它回送给线程函数。CreateThread将会返回一个线程ID和句柄给线程。线程ID是用来在系统中唯一确定线程的,并且可接受一些函数,例如AttachThreadInput等。

  你可以通过堆栈参数来控制线程堆栈的初始化大小。将堆栈参数设置为0将会令线程堆栈初始化为与它的父线程一样大。堆栈可以根据需要变大,不过增大堆栈会带来系统开销,因此你最好在开始就分配一个适合的大小,这可以通过它使用的局部变量的大小决定。你还可以唤醒一个挂起的线程。在挂起时,该线程将不会占用任何的CPU时间,直到其它线程通过ResumeThread唤醒它。

  对于延迟一个线程来说,上面代码中的休眠函数是一个有效的方法。在以前,你可能需要使用循环或者类似的技术来做到一个延迟,不过你也应该知道循环是不可靠的,并且会造成资源的浪费,因为循环也会使用CPU周期,这是不必要的。休眠函数可以延迟一个线程,而无需要花费任何的CPU周期。在休眠中,一个线程是完全挂起的。

  你要留意到全局变量count是使用volatile修饰符的。如果你注释掉线程中的Sleep函数,并且除去volatile修饰符,在你按在回车键时,count的值会保持为0。这是由于编译器的优化而造成的一个奇怪现象。例如,对于编译器来说,将可能使用一个寄存器来保存主线程中count变量的值,而忽略第二个线程对该值的修改。volatile修饰符的作用是告诉编译器无需对该变量作任何的优化,即无需要将它放到一个寄存器中,并且该值可在赋值期间被外部改变。你将会发现对于多线程引用的全局变量来说,volatile是一个非常重要的修饰符。

共4页。 9 7 1 2 3 4 8 :
文章阅读排行
周排行
月排行
欢迎订阅天极网RSS聚合资讯:http://www.yesky.com/index.xml