利用API在Windows下创建进程和线程文档格式.docx

上传人:b****4 文档编号:6610273 上传时间:2023-05-07 格式:DOCX 页数:15 大小:86.36KB
下载 相关 举报
利用API在Windows下创建进程和线程文档格式.docx_第1页
第1页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第2页
第2页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第3页
第3页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第4页
第4页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第5页
第5页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第6页
第6页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第7页
第7页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第8页
第8页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第9页
第9页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第10页
第10页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第11页
第11页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第12页
第12页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第13页
第13页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第14页
第14页 / 共15页
利用API在Windows下创建进程和线程文档格式.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

利用API在Windows下创建进程和线程文档格式.docx

《利用API在Windows下创建进程和线程文档格式.docx》由会员分享,可在线阅读,更多相关《利用API在Windows下创建进程和线程文档格式.docx(15页珍藏版)》请在冰点文库上搜索。

利用API在Windows下创建进程和线程文档格式.docx

scurrentdirectory

 LPSTARTUPINFOlpStartupInfo,//pointertoStartupInfo

 LPPROCESS_INFORMATIONlpProcessInformation 

 //pointertoPROCESS_INFORMATION 

  虽然有很多参数,不过在现阶段的实验级别,大多数参数只要用默认值即可。

  下面要做的关于Windows使用进程的实验,在Linux系统下,可以使用类似:

  execve(char*cmdName,char*cmdArgu)的语句从一个程序中去执行其它的程序。

  而如果在Windows下,当使用CreateProcess去执行相应的功能时,只要去改变cmdLine中的内容即可,其它的参数使用默认值,具体见代码1:

  代码1执行的功能是从命令行中启动这个名叫的launch的测试程序,在launch后面应加上保存有需要打开程序路径的文件名:

  如在命令行中键入:

>

launchset.txt

  而set.txt中的内容为:

C:

\\WINDOWS\\SYSTEM32\\CALC.EXE

\\WINDOWS\\SYSTEM32\\NOTEPAD.EXENEW.TXT

\\WINDOWS\\SYSTEM32\\CHARMAP.EXE

  路径的前半部分为”C:

\\WINDOWS\\”,这当然要视你的Windows系统的类型以及系统盘的存放位置而定。

如果是NT或2000的机器,则应使用WINNT.

/*测试程序1:

  示例如何使用进程的launch程序,通过在命令行中加载相应的命令文件,去按照命令文件中指定的程序路径打开相应的程序去执行*/

#include<

windows.h>

stdio.h>

string.h>

#defineMAX_LINE_LEN80

intmain(intargc,char*argv[])

{

//localvariables

FILE*fid;

charcmdLine[MAX_LINE_LEN];

//CreateProcessparameters

LPSECURITY_ATTRIBUTESprocessA=NULL;

//Default

LPSECURITY_ATTRIBUTESthreadA=NULL;

BOOLshareRights=TRUE;

DWORDcreationMask=CREATE_NEW_CONSOLE;

//Windowperprocess.

LPVOIDenviroment=NULL;

LPSTRcurDir=NULL;

STARTUPINFOstartInfo;

//Result

PROCESS_INFORMATIONprocInfo;

//1.Readthecommandlineparameters

if(argc!

=2)

fprintf(stderr,"

Usage:

lanch<

launch_set_filename>

\n"

);

exit(0);

}

//2.Openafilethatcoutainasetofcommands

fid=fopen(argv[1],"

r"

//3.Foreverycommandinthelaunchfile

while(fgets(cmdLine,MAX_LINE_LEN,fid)!

=NULL)

 //Readacommandfromthefile

 if(cmdLine[strlen(cmdLine)-1]=='

\n'

  cmdLine[strlen(cmdLine)-1]='

\0'

;

//RemoveNEWLINE

 //Createanewprocesstoexecutethecommand

 ZeroMemory(&

startInfo,sizeof(startInfo));

 startInfo.cb=sizeof(startInfo);

 if(!

   NULL,//Filenameofexecutable

   cmdLine,//commandline

   processA,//Processinheritedsecurity

   threadA,//Threadinheritedsecurity

   shareRights,//Rightspropagation

   creationMask,//variouscreationflags

   enviroment,//Enviromentvariable

   curDir,//Child'

   &

startInfo,

procInfo 

  )

 )

 fprintf(stderr,"

CreatProcessfailedonerror%d\n"

,GetLastError());

 ExitProcess(0);

//Terminateafterallcommandshavefinished.

return0;

  通过上面这段极其简洁的代码,完成了看似有些难度的任务,让我们充分感受到采用一些高级的编程手段所带来的便捷与高效.

2、Windows线程的创建及实验:

  2.1使用CreateThread在Windows下创建线程:

  在Windows中创建线程可以调用两个函数_beginthreadex和CreateThread两个函数,这里只介绍后者。

  CreateThread函数原型:

HANDLECreateThread

 (LPSECURITY_ATTRIBUTESlpThreadAttributes,//pointertothreadsecurityattributes

  DWORDdwStackSize,//initialthreadstacksize,inbytes

  LPSECURITY_START_ROUTINElpStartAddress,//pointertothreadfunction

  LPVOIDlpParameter,//argumentfornewthread

  DWORDdwCreationFlags,//creationflags

  LPDWORDlpThreadId//pointertoreturnedthreadidentifier

  其中,在本实验阶段比较重要的参数是第三和第四个:

  a)第三个参数是一个指向函数的指针,所以应传入的参数应为函数的地址,如&

Func的形式.而这个传入的参数,则必须被声明成为:

DWORDWINAPIthreadFunc(LPVOIDthreadArgu);

  的形式.这个函数也就是要执行线程任务的那个函数体实体.这里应注意,传入应使用Func而非&

Func。

  如:

CreateThread(NULL,0,Func,…)

  具体原因:

我目前认为是系函数前部使用WINAPI所致。

 

  b)第四个参数应是执行线程任务的函数体实体所需要的参数,即上面所举例的函数threadFunc的参数threadArgu,这在WINDOWS中被定义成一个LPVOID的类型,目前我认为,可以把它在功能上看成和void*类似。

  参考:

LPVOID的原型:

typedefvoidfar*LPVOID;

  所以,当你有自己需要的类型的参数传入时,可以用

typedefstruct 

intfirstArgu,

longsecArgu,

}myType,*pMyType;

  将你想要传入的参数装入一个结构体中。

  在传入点,使用类似:

pMyTypepMyTpeyArgu;

CreateThread(NULL,0,threadFunc,pMyTypeArgu,…);

  在函数threadFunc内部的接收点,可以使用“强行转换”,如:

intintValue=((pMyType)lpvoid)->

firstArgu;

longlongValue=((pMyType)lpvoid)->

secArgu;

……

  2.2线程实验1---创建N个随机线程,所有线程的执行时间均为T秒,观察每个线程的运行状况:

  为了使线程的运行趋于随机化,应先使用:

srand((unsignedint)time(NULL));

  在每个线程的运行中,每个线程的睡眠时间为:

sleepTime=1000+30*(int)eRandom(50+tNo);

Sleep(sleepTime);

  这样,可以使进程的运行趋于随机化.

/*测试程序2:

  创建N个随机线程的随机实验.

  命令行输入参数:

testthreadNorunSecs 

*/

math.h>

stdlib.h>

time.h>

#defineN5

#defineTypefloat

staticintrunFlag=TRUE;

DWORDWINAPIthreadWork(LPVOIDthreadNo);

intparseArgToInt(char*inNumChar);

TypeeRandom(intupLimit);

typedefstruct

 intdata;

}INTEGER;

voidmain(intargc,char*argv[])

 unsignedintrunTime;

 inti;

 intthreadNum;

 //intN;

 SYSTEMTIMEnow;

 WORDstopTimeMinute,stopTimeSecond;

 DWORDtargetThreadID;

 //Getcommandlineargument,N

 if(argc!

=3)

 {

  printf("

pleaseenter:

NThread<

ThreadNum>

<

runTime>

  return;

 }

 threadNum=parseArgToInt(argv[1]);

 runTime=parseArgToInt(argv[2]);

 //Getthetimethethreadsshouldrun,runtime

 //Calculatetimetohalt

 //runTime=60;

/*inseconds.*/

 GetSystemTime(&

now);

 printf("

mthread:

Suitestartingatysystemtime%d,%d,%d\n"

,now.wHour,now.wMinute,now.wSecond);

 stopTimeSecond=(now.wSecond+(WORD)runTime)%60;

 stopTimeMinute=now.wMinute+(now.wSecond+(WORD)runTime)/60;

 //FOR1TON

 INTEGER*tmpInt;

 for(i=0;

i<

threadNum;

i++)

  //CREATEANEWTHREADTOEXECUTESIMULATEDWORK;

  //threadWork(i);

  tmpInt=(INTEGER*)malloc(sizeof(INTEGER));

  tmpInt->

data=i;

  CreateThread(NULL,0,threadWork,tmpInt,0,&

targetThreadID);

  Sleep(100);

//Letnewlycreatedthreadrun

 //Cyclewhilechildrenwork...

 while(runFlag)

  GetSystemTime(&

  if((now.wMinute>

=stopTimeMinute)&

&

(now.wSecond>

=stopTimeSecond))

   runFlag=FALSE;

  Sleep(1000);

 Sleep(5000);

Programendssuccessfully\n"

DWORDWINAPIthreadWork(LPVOIDthreadNo)

 //localvariables

 doubley;

 constdoublex=3.14159;

 constdoublee=2.7183;

 constintnapTime=1000;

//inmilliseconds

 constintbusyTime=400;

 inttNo=((INTEGER*)threadNo)->

data;

 intsleepTime;

 DWORDresult=0;

 /*randomasizetherandomnumseeds.*/

 srand((unsignedint)time(NULL));

  //Parameterizedprocessorburstphase

  for(i=0;

busyTime;

  y=pow(x,e);

  //Parameterizedsleepphase

  sleepTime=1000+30*(int)eRandom(50+tNo);

  Sleep(sleepTime);

IamthreadNo.%d,sleepsec:

%ds\n"

,tNo,sleepTime);

 //Terminate

 returnresult;

intparseArgToInt(char*inNumChar)

 intequipData=0,i=0;

 while(inNumChar[i]>

='

0'

inNumChar[i]<

9'

  equipData=10*equipData+(inNumChar[i]-48);

  i++;

 returnequipData;

TypeeRandom(intupLimit)

 TypetmpData;

 do

  tmpData=((Type)rand()/(Type)32767)*(Type)100.0*(Type)upLimit;

 while(tmpData>

upLimit);

 returntmpData;

  2.3线程实验2---Windows下可创建的线程的数目的测试:

  这里使用的是让测试线程睡眠100秒,如果用的是让测试进程进入死循环的方法,则会很快让系统僵掉。

/*测试程序3:

测试在Windows下最多可创建线程的数目.

  Sleep(100000);

 intcount=0;

  

  if(CreateThread(NULL,0,threadWork,NULL,0,&

targetThreadID)==NULL)

  {

   runFlag=false;

   break;

  }

  else

   count++;

%d"

,count);

maxthreadsnum:

%d\n"

  在WindowsXP下(赛扬800MHZ,256M内存),在上述方式下,测得可创建的最多的线程数目为2030个.

 2.4线程实验3---最简单的一个临界资源的读者,写者程序.

  这个程序要实现的是最简单的读者,写者程序,读者将1~10十个数字依次填入临界资源区gData,当且仅当gData被读者消费后,写者才可以写入下一个数.

/*测试程序4:

最简单的一个临界资源的读者,写者程序.

DWORDWINAPIthreadReader(LPVOIDlpvoid)

 intreader_Data;

 intbusyTime=10000;

 floattmp;

 while(gRunFlag)

  while(stateFlag==WRITER_FLAG)

   for(i=0;

    tmp=pow(2,10);

    reader_Data=gData;

    printf("

readergetsdata:

,gData);

    stateFlag=WRITER_FLAG;

readerends\n"

 returnNULL;

DWORDWINAPIthreadWriter(LPVOIDlpvoid)

 intupTime=((INTEGER*)lpvoid)->

mInt;

  while(stateFlag==READER_FLAG)

   tmp=pow(2,10);

  gData++;

writergetsdata:

  if(gData==upTime)

   gRunFlag=false;

  stateFlag=READER_FLAG;

writerends\n"

/*Main中的调用*/

……

CreateThread(NULL,0,threadReader,tmpInt,0,&

CreateThread(NULL,0,threadWriter,tmpInt,0,&

  测试结果:

(如图2)

图2

  2.5几点说明:

  2.5.1主调用程序在结束时使用Sleep(5000)的意图在于:

使得由它所产生的子线程可以在主进程结束之前,完成如资源释放一类的工作。

  2.5.2在随机线程产生测试程序中:

  之所以采用在每个线程内部用

  去初始化每个线程,是为了使得所有的线程拥有自己的随机数种子,否则,如果是在主调用程序中去初始化随机数种子数,则所有的线程得到的随机数序列都是一样的,将无法产生随机效果。

  3、应用及推广:

  采用这种在Windows下利用控制台调用WindowsAPI进行操作系统实验的

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2