多线程学习基础.docx
《多线程学习基础.docx》由会员分享,可在线阅读,更多相关《多线程学习基础.docx(34页珍藏版)》请在冰豆网上搜索。
多线程学习基础
04.多线程通信多线程退出
#define_CRT_SECURE_NO_WARNINGS//强行的关闭安全检查
#include
#include
#include
#include
inti=0;
voidsettime(void*p)
{
while
(1)
{
charstr[40]={0};
sprintf(str,"title当前时间第%d秒",i);
system(str);//执行指令
i++;
Sleep(1000);
}
}
voidrun(void*p)
{
while
(1)
{
if(i==3)
{
system("calc");
}
elseif(i==10)
{
system("notepad");
_endthread();//退出线程的方式
}
elseif(i==13)
{
system("mspaint");
}
Sleep(100);
}
}
voidmain()
{
//system("titlechinaworld");
_beginthread(settime,0,NULL);
_beginthread(run,0,NULL);
system("pause");
}
05多线程并行检索
#include
#include
#include
#include
intisfind=0;//0代表没有找到,1代表找到
int*pfind=NULL;//为NULL没有找到,否则就是地址
structinfostract
{
int*pstart;//起始地址
intlength;//长度
intfindnum;//需要寻找的数字
intid;//线程编号
};
voidfind(void*p)
{
structinfostract*pinfo=(structinfostruct*)p;//获取参数地址
//检索指定内存
printf("线程%d开始查找\n",pinfo->id);
for(int*px=pinfo->pstart;pxpstart+pinfo->length;px++)
{
if(isfind==1)
{
printf("线程%d结束查找,其他线程已找到\n");
_endthread();
}
if(*px==pinfo->findnum)//判断是否相等
{
pfind=px;//返回找到的地址
isfind=1;//设置标识符找到
printf("线程%d结束查找,找到%d,%p\n",pinfo->id,*px,px);
_endthread();//退出
}
}
printf("线程%d结束查找,没有找到\n",pinfo->id);
}
voidmain()
{
intdata[1000]={0};
for(inti=999;i>=0;i--)
{
data[i]=i;
}
structinfostractmyinfo[10];
for(inti=0;i<10;i++)
{
myinfo[i].pstart=data+i*100;//设定地址
myinfo[i].length=100;
myinfo[i].id=i;
myinfo[i].findnum=767;
_beginthread(find,0,&myinfo[i]);//多线程查找
}
system("pause");
}
06多线程切割检索
整除时,直接整除即可;不整除的话处理n-1个线程的值。
前n-1个的为
#define_CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
intisfind=0;//0代表没有找到,1代表找到
int*pfind=NULL;//为NULL没有找到,否则就是地址
structinfostruct
{
int*pstart;//起始地址
intlength;//长度
intfindnum;//需要寻找的数字
intid;//线程编号
};
voidfind(void*p)
{
structinfostruct*pinfo=(structinfostruct*)p;//获取参数地址
//检索指定内存
printf("线程%d开始查找\n",pinfo->id);
for(int*px=pinfo->pstart;pxpstart+pinfo->length;px++)
{
if(isfind==1)
{
printf("线程%d结束查找,其他线程已找到\n");
_endthread();
}
if(*px==pinfo->findnum)//判断是否相等
{
pfind=px;//返回找到的地址
isfind=1;//设置标识符找到
printf("线程%d结束查找,找到%d,%p\n",pinfo->id,*px,px);
_endthread();//退出
}
}
printf("线程%d结束查找,没有找到\n",pinfo->id);
}
voidmain()
{
intdata[1000]={0};
for(inti=999;i>=0;i--)
{
data[i]=i;
}
intthreadnum;//线程数量
scanf("%d",&threadnum);
inttofindnum;//查找的数据
scanf("%d",&tofindnum);
if(1000%threadnum==0)//整除
{
//动态分配数组,提供给多线程传递参数
structinfostruct*pthrad=malloc(sizeof(structinfostruct)*threadnum);
for(inti=0;i{
pthrad[i].pstart=data+i*(1000/threadnum);
pthrad[i].length=1000/threadnum;
pthrad[i].id=i;
pthrad[i].findnum=tofindnum;//查找的数据
_beginthread(find,0,&pthrad[i]);//传递参数
}
}
else
{
//动态分配数组,提供给多线程传递参数
structinfostruct*pthrad=malloc(sizeof(structinfostruct)*threadnum);
for(inti=0;i{
pthrad[i].pstart=data+i*(1000/(threadnum-1));
pthrad[i].length=1000/(threadnum-1);
pthrad[i].id=i;
pthrad[i].findnum=tofindnum;//查找的数据
_beginthread(find,0,&pthrad[i]);//传递参数
}
{
inti=threadnum-1;
pthrad[i].pstart=data+1000/(threadnum-1)*(threadnum-1);
pthrad[i].length=1000-1000/(threadnum-1)*(threadnum-1);
pthrad[i].id=i;
pthrad[i].findnum=tofindnum;
_beginthread(find,0,&pthrad[i]);//传递参数
}
}
system("pause");
}
voidmain最理想()
{
intdata[1000]={0};
for(inti=999;i>=0;i--)
{
data[i]=i;
}
structinfostructmyinfo[10];
for(inti=0;i<10;i++)
{
myinfo[i].pstart=data+i*100;//设定地址
myinfo[i].length=100;
myinfo[i].id=i;
myinfo[i].findnum=767;
_beginthread(find,0,&myinfo[i]);//多线程查找
}
system("pause");
}
//重要知识点:
/*
不使用取模符号,如何实现取模操作
100%7=100-100/7*7
system("pause"):
system就是调用从程序中调用系统命令(和shell命令)。
system("pause")就是从程序里调用“pause”命令;
而“pause”这个系统命令的功能很简单,就是在命令行上输出一行类似于“Pressanykeytoexit”的字,等待用户按一个键,然后返回。
*/
07多线程(临界区有问题)
#include
#include
#include
#include
#include
CRITICAL_SECTIONcs;//临界区,定义为全局变量
intnum=0;//多线程发生冲突,
DWORDWINAPImyfun(void*p)
{
for(inti=0;i<100;i++)
{
//EnterCriticalSection(&cs);//进入临界区
num++;
//LeaveCriticalSection(&cs);//离开临界区
//Sleep(10);
}
return0;
}
voidmain()
{
time_tstart,end;
time(&start);
HANDLEhd[100];//线程数组
for(inti=0;i<100;i++)
{
hd[i]=CreateThread(NULL,0,myfun,NULL,0,NULL);
//WaitForSingleObject(hd[i],INFINITE);//同步
}
WaitForMultipleObjects(100,hd,TRUE,INFINITE);//等待所有线程退出
time(&end);
printf("\n%f",difftime(end,start));
printf("\n%d\n",num);
DeleteCriticalSection(&cs);
system("pause");
}
08.线程临界区
#include
#include
#include
#defineN64//临界区最大的线程为64
CRITICAL_SECTIONcs1;
CRITICAL_SECTIONcs2;//定义临界区,为了避免访问同一变量时,线程的冲突问题
intnum=0;
DWORDWINAPIadd(void*p)
{
EnterCriticalSection(&cs1);
for(inti=0;i<100000;i++)
{
num++;
}
LeaveCriticalSection(&cs1);
return0;
}
DWORDWINAPIsub(void*p)
{
EnterCriticalSection(&cs2);
for(inti=0;i<100000;i++)
{
num--;
}
LeaveCriticalSection(&cs2);
return0;
}
voidmain()
{
InitializeCriticalSection(&cs1);//初始化
InitializeCriticalSection(&cs2);//初始化
{
HANDLEhd[N];
for(inti=0;i{
hd[i]=CreateThread(NULL,0,add,NULL,0,NULL);//创建线程
//WaitForSingleObject(hd[i],INFINITE);
}
WaitForMultipleObjects(N,hd,TRUE,INFINITE);//等待全部退出
printf("num=%d\n",num);
}
{
HANDLEhd[N];
for(inti=0;i{
hd[i]=CreateThread(NULL,0,sub,NULL,0,NULL);//创建线程
//WaitForSingleObject(hd[i],INFINITE);
}
WaitForMultipleObjects(N,hd,TRUE,INFINITE);//等待全部退出
printf("num=%d\n",num);
}
DeleteCriticalSection(&cs1);
DeleteCriticalSection(&cs2);
system("pause");
}
09.操作线程
#include
#include
#include
//_beginthreadcreatethread创建
//endthread,exithread,内部结束,terminate外部结束
//SuspendThread(hd);//冻结ResumeThread(hd);//解冻
DWORDWINAPIfun(void*p)
{
inti=0;
while(++i)
{
printf("\n%d",i);
if(i>8000)
{
//_endthread();//用于线程内部退出
//ExitThread(0);//用于线程内部退出
}
}
return0;
}
//主线程,主导作用,管理调用其他线程
voidmain()
{
HANDLEhd=CreateThread(NULL,0,fun,NULL,0,NULL);
system("pause");
SuspendThread(hd);//冻结
system("pause");
ResumeThread(hd);//解冻
system("pause");
TerminateThread(hd,0);
system("pause");
}
10.定时器同步
#include
#include
#include
//单独定时器只能用于同步通信
voidmain1()
HANDLEtimer=CreateWaitableTimer(NULL,TRUE,NULL);//创建定时器
if(timer==NULL)
{
return;
}
else
{
LARGE_INTEGERtime;
time.QuadPart=-20000000;//2秒
//10^-7秒0.1微秒
SetWaitableTimer(timer,&time,0,NULL,0,NULL);//设置定时器等待2秒
if(WaitForSingleObject(timer,INFINITE)==WAIT_OBJECT_0)
{
printf("等待成功\n");
}
else
{
printf("等待失败\n");
}
}
system("pause");
}
HANDLEtimer;
DWORDWINAPIgo1(void*p)
{
MessageBoxA(0,"1","1",0);
timer=CreateWaitableTimer(NULL,TRUE,NULL);//创建定时器
LARGE_INTEGERtime;
time.QuadPart=-50000000;//5秒
SetWaitableTimer(timer,&time,0,NULL,0,NULL);//设置定时器等待2秒
}
DWORDWINAPIgo2(void*p)
{
MessageBoxA(0,"2","2",0);
}
voidmain()
{
HANDLEhd=CreateThread(NULL,0,go1,NULL,0,NULL);
WaitForSingleObject(hd,INFINITE);
if(WaitForSingleObject(timer,INFINITE)==WAIT_OBJECT_0)
//WAIT_OBJECT_0:
指定的对象处有信号状态
{
CreateThread(NULL,0,go2,NULL,0,NULL);
printf("等待成功\n");
}
else
{
printf("等待失败\n");
}
getchar();
}
注意:
(1)WaitForSingleObject(hd,INFINITE)
dwMilliseconds[in]定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了才返回。
如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。
如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。
11.线程事件
#define_CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
HANDLEevent[4]={0};//事件,事件是为了让不同线程之间实现通信,HANDLE=void*
HANDLEhthread[3]={0};//代表线程
CRITICAL_SECTIONcs;
charstr[1024]={0};//代表聊天内容缓冲区
//0海华发给媒婆0
//1媒婆发给王芳1
//2王芳通知媒婆2
//3媒婆发给海华3
DWORDWINAPIzhouruifu(void*p)
{
inti=0;
while(++i)
{
WaitForSingleObject(event[0],INFINITE);
EnterCriticalSection(&cs);
printf("\n媒婆传递%s",str);
LeaveCriticalSection(&cs);
Sleep(1000);
SetEvent(event[1]);//通知芳芳
WaitForSingleObject(event[2],INFINITE);
EnterCriticalSection(&cs);
printf("\n媒婆传递%s",str);
LeaveCriticalSection(&cs);
Sleep(1000);
SetEvent(event[3]);//通知海华
}
}
DWORDWINAPIhaihua(void*p)
{
inti=1;
EnterCriticalSection(&cs);
memset(str,'\0',1024);
sprintf(str,"\n海华第%d次说:
Iloveyoufangfang",i);
LeaveCriticalSection(&cs);
Sleep(1000);
SetEvent(event[0]);
while(++i)
{
WaitForSingleObject(event[3],INFINITE);
EnterCriticalSection(&cs);
memset(str,'\0',1024);
sprintf(str,"\n海华第%d次说:
Iloveyoufangfang",i);
LeaveCriticalSection(&cs);
Sleep(1000);
SetEvent(event[0]);
}
return0;
}
DWORDWINAPIfangfang(void*p)
{
inti=0;
while(++i)
{
WaitForSingleObject(event[1],INFINITE);
EnterCriticalSection(&cs);
memset(str,'\0',1024);