文档库 最新最全的文档下载
当前位置:文档库 › 在VC_中利用API实现多线程编程实例

在VC_中利用API实现多线程编程实例

在VC_中利用API实现多线程编程实例
在VC_中利用API实现多线程编程实例

在VC ++中利用API 实现多线程编程实例

Ξ

张智丰1,张亚荣2,包丽梅1

(1.内蒙古民族大学数学与计算机科学学院,内蒙古通辽 028043;2.通辽职业学院,内蒙古通辽 028000)〔摘 要〕32位Windows 环境下的Win32API 提供了一些多线程应用程序开发所需要的接口函数,本文介绍

了一种在Visual C ++中利用Win32API 编制多线程程序的实例,有助于加深对Windows 多线程编程技术的

认识及理解.

〔关键词〕Visual C ++;Win32API ;多线程

〔中图分类号〕TP312 〔文献标识码〕A 〔文章编号〕1671-0185(2008)04-0382-04

The C ase to R ealize Multi -thread

Programming B ased on API in VC ++

ZHAN G Zhi -feng 1,ZHAN G Ya -rong 2,BAO Li -mei 1

(1.C ollege of Mathematics and C om puter S cience ,Inner M ong olia University for Nationalities ,T ongliao 028043,China ;

2.T ongliao Professional C ollege ,T ongliao 028000,China )

Abstract :Win32API which under 32-bit windows provides some interface functions required for

development of multi -thread application.In this article ,a case to realize Multi -thread pro 2

gramming based on API in VC ++is introduced.It will help to deepen our cognition and com 2

prehension for Multi -thread programming technique.

K ey w ords :Visual C ++;Win32API ;Multi -thread

线程是近年来在操作系统领域中出现的一个非常重要的机制和技术,其重要程度一点也不亚于进程〔1〕.线程机制提高了程序执行的有效性,同时也方便了用户组织和编写他的程序.因此它不但适用于多机系统,而且对大多数的单CPU 的个人计算机也同样带来好处.

多线程就是在一个进程内有多个线程,从而使一个应用程序有了多任务的功能.有人会问:多进程技术不是也可以实现这一点吗?但是创建进程的高消耗(每个进程都有独立的数据和代码空间),进程之间通信的不方便(消息机制),进程切换的时间太长,这些导致了多线程的提出.提供多线程机制的好处是:当一个应用是由若干个相对独立的任务构成时特别有用,便于这些任务同时、并行运行,大大提高了工作效率和资源利用率.

Win32API 是Windows 操作系统内核与应用程序之间的接口〔2〕,它将内核提供的功能进行函数包

装,应用程序通过调用相关函数而获得相应的系统功能.为了向应用程序提供多线程功能,Win32API 函数集中提供了一些处理多线程程序的函数集.虽然它要求程序员编写的代码较多,且需要管理所有系统提供给程序的资源,但是直接用Win32API 进行程序设计还是具有很多优点:基于Win32的应用程序执行代码小,运行效率高.

下面是在C ++中利用Win32API 函数编写C 风格的多线程应用程序实例,该实例主要实现著名的Ξ收稿日期:2007-12-10

作者简介:张智丰(1972-),男,内蒙古通辽人,讲师.

第23卷 第4期

内蒙古民族大学学报(自然科学版)Vol.23 No.42008年7月Journal of Inner Mongolia University for Nationalities J ul.2008

“生产者与消费者的问题”

(完全可编译执行).具体涉及到如下几个多线程API 函数:1 Win32API 函数创建和终止线程

在应用程序的主线程或者其他活动线程中创建新的线程的函数如下:

HANDL E Create Thread (L PSECU RIT Y 2A TTRIBU TES lp ThreadAttributes ,DWORD dwStackSize ,L PTHREAD 2STAR T 2ROU TIN E lpStartAddress ,L PVO ID lp Parameter ,DWORD dwCreationFlags ,L PDWORD lp ThreadId );

如果创建成功则返回线程的句柄,否则返回NULL.通过对参数dwCreationFlags 的设置,可使新的线程被创建后,或者被挂起或者立即启动执行.

线程被创建后,正常情况下就运行直到线程函数返回.用户也可调用下面两个函数来终止线程:VO ID Exit Thread (DWORD dwStatus );

BOOL Terminate Thread (HANDL E h Thread ,DWORD dwStatus );

Exit Thread ()将正常终止线程,一个线程函数如果调用Exit Thread ()等价于使用return 返回,而一个线程通过调用Terminate Thread ()可以强迫另一个线程立刻停止.

2 Win32API 函数实现线程的同步

线程之间经常要同时访问一些资源.由于对共享资源进行访问引起冲突是不可避免的,为了解决这种线程同步问题,Win32API 提供了多种同步机制来帮助程序员解决共享资源访问冲突.在介绍这些同步机制之前先介绍一下等待函数,因为所有控制对象的访问控制都要用到这两个函数:

DWORD Wait ForSingleObject (HANDL E ,DWORD dwMilliseconds );

DWORD Wait ForMultipleObject (DWORD nCount ,CONST HANDL E 3lp Handles ,BOOL bWaitAll ,DWORD dwMilliseconds );

这两个函数在其参数中的一个或多个同步对象产生了信号,或者超过规定的等待时间才会返回.在等待函数未返回时,线程处于等待状态,此时线程只消耗很少的CPU 时间.

在WIN32中,同步机制主要有以下几种:信号量、临界区、互斥量、事件等〔3〕,在本例中主要使用了信

号量机制.与此机制相关的有如下几个API 函数:

HANDL E CreateSemaphore (L PSECU RIT Y 2A TTRIBU TES lpSecAttr ,LON G InitialCoutn ,LON G lMaxCount ,L PCTSTR lpszSemName );

BOOL ReleaseSemaphore (HANDL E hSema ,LON G lReleaseCount ,L PLON G lp Previous );

首先,通过CreateSemaphore ()创建信号量;然后,在线程访问共享资源之前调用Wait ForSingleObject

();共享资源访问完成后,应使用ReleaseSemaphore ()释放对信号量对象.在这里,假定信号量为S ,则Wait ForSingleObject (S )相当于PV 原语中的P (S )操作;而ReleaseSemaphore (S )相当于PV 原语中的V (S )操作.

3 多线程实例实现

/3productandconsumer.cpp 3/

#include

#include

#include

typedef HANDL E Semaphore ;//信号量的Windows 原型

#define P (S )Wait ForSingleObject (S ,IN FIN ITE )//定义P 操作

#define V (S )ReleaseSemaphore (S ,1,NULL )//定义V 操作

#define CONSUM ER 2NUM 10/3消费者个数3/

#define PRODUCER 2NUM 10/3生产者个数3/

#define BU FFER 2NUM 5/3缓冲区个数3/

char 3fruit [10]={″桔子″,″苹果″,″香蕉″,″菠萝″,″草莓″,″荔枝″,″樱桃″,″葡萄″,″桃子″,″鸭梨″};

3

83第4期张智丰等:在VC ++中利用API 实现多线程编程实例

struct Buffer

{int buf[BU FFER2NUM];//缓冲区

int out,in;//两个指针

}pub2buf;

Semaphore empty,full,mutex;

//消费者线程

DWORD WINAPI Consumer(L PVO ID para) {//i表示第i个消费者

int i=3(int3)para;

int ptr;//待消费的内容的指针

printf(″消费者%03d:我来啦!\n″i);

Sleep(300);

while(1)

{printf(″消费者%03d:我要吃.........

!\n″,i);

P(full);//等待产品

P(mutex);//有产品,先锁住缓冲区g2buf

 ptr=pub2buf.out;//记录消费的物品

 pub2buf.out=(pub2buf.out+1)%BU FFER2NUM;//再移动缓冲区指针

 V(mutex);//让其他消费者或生产者使用g2buf

 printf(″消费者%03d:我吃buf[%d]=%s\n″,i,ptr,fruit[pub2buf.buf[ptr]]);

 Sleep(10003rand()%10+110);

 printf(″消费者%03d:我吃完了!buf[%d]=%s\n″,i,ptr,fruit[pub2buf.buf[ptr]]);

 V(empty);//消费完毕,并释放一个缓冲}

return0;}

//生产者线程

DWORD WINAPI Producer(L PVO ID para)

{int i=3(int3)para-CONSUM ER2NUM;

int ptr;int data;//产品

printf(″生产者%03d:我来啦!\n″,i);

Sleep(300);

while(1)

{printf(″生产者%03d:我生产!…………\n″,i);

Sleep(10003rand()%10+110);

data=rand()%10;

printf(″生产者%03d:送来一个水果data=%s!\n″,i,fruit[data]);

P(empty);

P(mutex);//有地方,先锁住缓冲区pub2buf

ptr=g2buf.in;//记录消费的物品

g2buf.in=(g2buf.in+1)%BU FFER2NUM;

V(mutex);//让其他消费者或生产者使用pub2buf

printf(″生产者%03d:搁到buf[%d]=%s\n″,i,ptr,fruit[data]);

pub2buf.buf[ptr]=data;

Sleep(1000/23rand()%10+110);

483内 蒙 古 民 族 大 学 学 报2008年

printf (″生产者%03d :buf [%d ]=%s 放好了,大家吃!\n ″,i ,ptr ,fruit [pub 2buf.buf [ptr ]]);V (full );//放好了完毕,释放一个产品}

return 0;}

int main ()

{//线程技术,前面为消费者线程,后面为生产者线程

HANDL E Threadgroup [CONSUM ER 2NUM +PRODUCER 2NUM ];//线程计数

DWORD tid ;int i =0;

//初始化信号量

mutex =CreateSemaphore (NULL ,1,BU FFER 2NUM ,mutexOfC &P ″

);empty =CreateSemaphore (NULL ,BU FFER 2NUM ,BU FFER 2NUM ,“emptyBuffer ”

);full =CreateSemaphore (NULL ,0,BU FFER 2NUM ,“fullBuffer ”

); if (!empty ||!full ||!mutex )

{printf (“

Create Semaphone Error !\n ”); return -1;}

 int total Threads =CONSUM ER 2NUM +PRODUCER 2NUM ;

 for (i =0;i

{Threadgroup [i ]=Create Thread (NULL ,0,Consumer ,&i ,0,&tid );

if (Threadgroup [i ])Wait ForSingleObject (Threadgroup [i ],10);}

 for (;i

{Threadgroup [i ]=Create Thread (NULL ,0,Producer ,&i ,0,&tid );

if (Threadgroup [i ])Wait ForSingleObject (Threadgroup [i ],10);}

//生产者和消费者的执行

 Wait ForMultipleObjects (total Threads ,Threadgroup ,false ,IN FIN ITE );

}

4 结束语

如果用户的应用程序需要多个任务同时进行相应的处理,则使用多线程是较理想的选择.这里,提醒大家注意的是在多线程编程时要特别小心处理资源共享问题以及多线程调试问题.多线程编程是一门比较复杂的技术,它不仅要求有熟练的编程技术,还要求对操作系统内部有深入的了解.它在程序设计思路上不同于传统的模块结构化方法,比一般的面向对象方法也较为复杂,尤其是线程间的同步问题.除了VC ++外,VB 、Delphi 等也提供了对多线程编程的支持,但总的说来,VC ++的功能最为强大,限于篇幅,不能详尽探讨.

参 考 文 献〔1〕屠祁.操作系统基础〔M 〕.北京:清华大学出版社,2000.

〔2〕Jim Beveridge ,Robert Wiener.Win32多线程设计〔M 〕.武汉:华中科技大学出版社,2002.

〔3〕王险峰.Windows 环境下的多线程编程原理与应用〔M 〕.北京:清华大学出版社,2002.

〔责任编辑 郑 瑛〕583第4期张智丰等:在VC ++中利用API 实现多线程编程实例

相关文档