2024年9月c多线程编程实例(VC++ 最简单的多线程)
⑴c多线程编程实例(VC++最简单的多线程
⑵VC++最简单的多线程
⑶#include《windows.h》#include《iostream》usingnamespacestd;DWORDWINAPIMyThread(PVOIDpvParam){for(inta=;a《;a++){cout《《“Thread“《《endl;Sleep();}return;}DWORDWINAPIMyThread(PVOIDpvParam){for(intb=;b《;b++){cout《《“Thread“《《endl;Sleep();}return;}DWORDWINAPIMyThread(PVOIDpvParam){for(intc=;c《;c++){cout《《“Thread“《《endl;Sleep();}return;}intmain(){HANDLEhThread=CreateThread(NULL,,MyThread,NULL,,NULL);HANDLEhThread=CreateThread(NULL,,MyThread,NULL,,NULL);HANDLEhThread=CreateThread(NULL,,MyThread,NULL,,NULL);Sleep();cout《《“Main“《《endl;CloseHandle(hThread);CloseHandle(hThread);CloseHandle(hThread);return;}首先创建一个线程实用APICreateThread,还有就是一个线程函数的原型.HANDLECreateThread(LPSECURITY_ATTRIBUTESlpsa,DWORDcbStack,LPTHREAD_START_ROUTINElpStartAddr,LPVOIDlpvThreadParam,DWORDfdwCreate,LPDWORDlpIDThread);DWORDWINAPIThreadProc(LPVOIDlpParameter);还有就是Sleep这个函数是放弃自己运行的时间片....
⑷如何用c++builder编写多线程
⑸摘要:本文简单介绍了Windows环境下进行多线程编程的意义,重点讨论了C++Builder环境下开发多线程应用程序这一问题,并通过实现生产者-消费者问题,帮我们更好地理解同步概念及其实现方法。关键词:多线程;同步;生产者-消费者;C++Builder线程之可行性在很多情况下,可能需要为程序创建线程。这里给出其中一些可能性:()如果创建的是一个多文档接口(MultipleDocumentInterface,MDI程序,那么为每个窗口分配一个线程就显得十分重要了,例如,对于一个通过多个Modem同时连接到多个主机的MDI通信程序而言,如果每个窗口都有它自己的线程来和一个主机通信,那么整个事情就简化很多。()如果使用的是一台有多个处理器的机器,并希望充分利用所有可能获得的CPU资源,那么就需要将应用程序分解成多个线程。Windows中CPU的划分单位为线程。因此,如果程序只包含一个线程,那么,默认环境下该程序只能使用其中一个CPU。但是,如果将此程序划分为多个线程,那么Windows就可以在不同的CPU上运行各个线程。()在后台运行的某些任务的同时,要求用户还可以继续使用应用程序进行工作。利用线程很容易实现这点。例如:可以将一些冗长的重算、页面格式化操作、文件的读写等活动都放在单独的线程中,使其在后台运行,而不会对用户造成影响。同步撰写多线程程序的一个最具挑战性的问题就是:如何让一个线程和另一个线程合作。这引出了一个非常重要的问题:同步。所谓同步是指进程、线程间相互通信时避免破坏各自数据的能力。Windows环境下的同步问题是由Win系统的CPU时间片分配方式引起的。虽然在某一时刻,只有一个线程占用CPU(单CPU时间,但是无法知道在什么时候,在什么地方线程被打断,这样如何保证线程之间不破坏彼此的数据就显得格外重要。同步问题是如此重要,也相当有趣,因而吸引了不少学者对他进行研究,由此产成了一系列经典的进程同步问题,其中较有代表性的是“生产者-消费者问题“、“读者-写者问题““哲学家进餐问题“等。在此,本文简要讨论了C++Builder平台下如何利用多线程编程技术实现“生产者-消费者“问题,帮助我们更好得理解同步概念及其实现方法。生产者-消费者问题生产者-消费者问题是一个著名的进程同步问题。它描述的是:有一群生产者进程在生产消息,并将此消息提供给消费者进程去消费。为使生产者进程和消费者进程能并发进行,在他们之间设置了一个具有N个缓冲区的缓冲池,生产者进程可以将它所生产的消息放入一个缓冲区中,消费者进程可以从一个缓冲区中取得一个消息消费。尽管所有的生产者进程和消费者进程都是以异步方式进行的,但他们之间必须保持同步,即不允许消费者进程到一个空的缓冲区中去取消息,也不允许生产者进程向一个已装满消息且尚未被取走消息的缓冲区中投放消息。C++Builder多线程应用程序编程基础、使用C++Builder提供的TThread类VCL类库提供了用于线程编程的TThread类。在TThread类中封装了Windows中关于线程机制的WindowsAPI。对于大多数的应用程序来说,可在应用程序中使用线程对象来表示执行线程。线程对象通过封装使用线程所需的内容,简化了多线程应用程序的编写。注意,线程对象不允许控制线程堆栈的大小或其安全属性。若需要控制这些,必须使用WindowsAPI的CreateThread()或BeginThread()函数。TThread类有以下一些属性和方法:)属性:·Priority:优先级属性。可以设置线程的优先级。·ReturnValue:返回值属性。当线程介绍时返回给其他线程一个数值。·Suspended:挂起属性。可以判断线程是否被挂起。·Terminated:结束属性。用来标志是否应该结束线程。·ThreadID:标识号属性。在整个系统中线程的标识号。使用WindowsAPI函数时该属性非常有用。方法:·DoTerminate:产生一个OnTerminate事件,但是不结束线程的执行。·Resume:唤醒一个线程继续执行。·Suspend:挂起一个线程,要与Resume过程成对使用。·Synchronize:由主VCL线程调用的一个同步过程。·Terminate:将Terminate属性设置为True,中止线程的执行。·WaitFor:等待线程的中止并返回ReturnValue属性的数值。、协调线程在编写线程执行时运行的代码时,必须考虑到可能同步执行的其他线程的行为。特别注意,避免两个线程试图同时使用相同的全局对象或变量。另外,一个线程中的代码会依赖其他线程执行任务的结果。避免同时访问为避免在访问全局对象或变量时与其他线程发生冲突,可能需要暂停其他线程的执行,直到该线程代码完成操作。()锁定对象。一些对象内置了锁定功能,以防止其他线程使用该对象的实例。例如,画布对象(TCanvas及其派生类有一种Lock(函数可以防止其他线程访问画布,直到调用Unlock(函数。显然,这种方法只对部分类有效。()使用重要区段。若对象没有提供内置的锁定功能,可使用重要区段。重要区段像门一样,每次只允许一个线程进入,要使用重要区段,需创建TCriticalSection的全局实例。TCriticalSection有两个函数:Acquire((阻止其他线程执行该区域及Release((取消对其他线程的阻止。()使用多重读、独占写的同步器。当使用重要区段来保护全局内存时,每次只有一个线程可以使用该内存。这种保护可能会超出了需要,特别是有一个经常读但很少写的对象或变量时更是如此。多个线程同时读相同内存但没有线程写内存是没有危险的。当有一些经常被读,但是很少写的全局变量时,可用TMultiReadExclusiveWriteSynchronizer对象保护它。这个对象和重要区段一样,但它允许多个线程同时读,只要没有线程写即可。每个需要读内存的线程首先要调用BeginRead(函数(确保当前无其他线程写内存,线程完成对保护内存读操作后,要调用EndRead(函数。任何线程需要写保护内存必须调用BeginWrite(函数(确保当前无其他线程读或写内存,完成对保护内存写操作后,调用EndWrite(函数。()使用Synchronize函数:Void__fastcallSynchronize(TThreadMethod&Method);其中参数Method为一个不带参数的过程名。在这个不带参数的过程中是一些访问VCL的代码。我们可以在Execute过程中调用Synchronize过程来避免对VCL的并发访问。程序运行期间的具体过程实际上是由Synchronize过程来通知主线程,然后主线程在适当的时机来执行Synchronize过程的参数列表中的那个不带参数的过程。在多个线程的情况下,主线程将Synchronize过程发过来的通知放到消息队列中,然后逐个地响应这些消息。通过这种机制Synchronize实现了线程之间地同步。)等待其他线程若线程必须等待另一线程完成某项任务,可让线程临时中断执行。然后,要么等待另一线程完全执行结束,要么等待另一线程通知完成了该任务。()等待线程执行结束要等待另一线程执行结束,使用它地WaitFor(函数。WaitFor函数直到那个线程终止才返回,终止的方式要么完成了其Execute(函数,要么由于一个异常。()等待任务完成。有时,只需要等待线程完成一些操作而不是等待线程执行结束。为此,可使用一个事件对象。事件对象(TEvent应具有全局范围以便他们能够为所有线程可见。当一个线程完成一个被其他线程依赖的操作时,调用TEvent::SetEvent(函数。SetEvent发出一个信号,以便其他线程可以检查并得知操作完成。要关掉信号,则使用ResetEvent()函数。例如,当必须等待若干线程完成其执行而不是单个线程时。因为不知道哪个线程最后完成,也就不能对某个线程使用WaitFor(函数。此时,可通过调用SetEvent以在线程结束时累加计数值并在最后一个线程结束时发出信号以指示所有线程结束。多线程应用程序编程实例下面是一个实现“生产者-消费者问题“的多线程应用实例。在此例中,我们按上面介绍的方法构造了两个TThread的子类TProducerThread(生产者线程和TCustomerThread(消费者线程,生产和消费的商品仅仅是一个整数。在协调生产和消费的过程中,重要区段(TCriticalSection和事件(TEvent得到了应用。生产者通过TEvent类的对象BeginConsume来通知消费者开始消费,而消费者通过TEent类的对象BeginProduce通知生产者开始生产。程序中共有两个生产者,一个消费者。在两个生产者之间,通过TCriticalSection类的对象同步。其运行界面如图所示。图程序运行效果主要源程序如下所示:生产者线程:Void__fastcallTProducerThread::Execute(){//----Placethreadcodehere----Inti=;Intj;while(i《)//每个生产者线程生产个商品{Sleep();//延迟,为清楚得显示执行效果if(Form-》buffer_size》)//缓冲池不空,通知消费者消费{Form-》BeginConsumer-》SetEvent();}Form-》ProduceGuard-》Acquire();i++;StrResult=IntToStr(i);J=Form-》buffer_size;Form-》Product=i;Form-》buffer_size++;Synchron转载,仅供参考,祝你愉快,满意请采纳。
⑹c语言中怎样创建多线程最好有一个例子,谢谢!!
⑺/*这是我写的最简单的多线程程序,看懂不?*/#include《windows.h》#include《stdio.h》//#include《strsafe.h》DWORDWINAPIThreadProc(LPVOIDlpParam){inti=,j=;while(){printf(“hello,thisthread...
⑻“);//延时for(i=;i《;i++){;}}}DWORDWINAPIThreadProc(LPVOIDlpParam){inti=,j=;while(){printf(“hello,thisthread...
⑼“);//延时for(i=;i《;i++){;}}}voidmain(){inti=;//创建线程CreateThread(NULL,//defaultsecurityattributes,//usedefaultstacksizeThreadProc,//threadfunctionNULL,//argumenttothreadfunction,//usedefaultcreationflagsNULL);//returnsthethreadidentifier//创建线程CreateThread(NULL,//defaultsecurityattributes,//usedefaultstacksizeThreadProc,//threadfunctionNULL,//argumenttothreadfunction,//usedefaultcreationflagsNULL);//returnsthethreadidentifier//让主线程进入循环,主线程若退出,子线程,会被系统“杀死”while(){printf(“hello,thisthread...
⑽“);//延时for(i=;i《;i++){;}}}
⑾C语言怎样实现多线程
⑿首先你要有控制蛇移动方向的全局变量(定义在main以外因为线程函数也要调用它,每次键盘输入都会修改它的值,比如chardirection’a’==左’w’==右’d’==上’s’==下,然后你在移动时应该是在while里面操作的吧,你每移动一步前都读一下direction这个变量的数值然后再控制移动方向(注意s这个键可以忽略因为不会倒着走然后你可以用pthread.h这个库例子是pthreadt;//定义一个线程pthread_create(&t,null,listen_keyboard_input,null);//建立线程执行listen_keyboard_input这个函数这个线程执行的函数voidlisten_keyboard_input(){while(应该通过某个信号来退出这个循环,从而表示游戏结束){direction=getchar();}}但是这里存在同步问题,比如当这个线程的getchar(在给direction辅助的同时,你控制贪吃蛇移动的线程正在调用direction的值来判断下一个移动方向,这就会出问题,所以要加一个锁,叫mutexlock;这个也定义成全局变量可以使各线程共享。pthread_mutex_tmutex;//定义一个锁pthread_mutex_init(&mutex,null,null);//初始化然后把函数修改成voidlisten_keyboard_input(){while(应该通过某个信号来退出这个循环,从而表示游戏结束){pthread_mutex_lock(&mutex);direction=getchar();pthread_mutex_unlock(&mutex);}}另外一个控制贪吃蛇移动的时候也要加锁while(.....){charc;pthread_mutex_lock(&mutex);c=direction;pthread_mutex_unlock(&mutex);switch(c){................}...................................}这样就好了注意你的控制贪吃蛇移动的部分也必须要放在另外一个pthread里面执行,如果放在主线程,主线程会一直等listen_keyboard_input而什么事都不会做你把这两个线程用pthread_create创建完成后用t.join();t.join();就可以使这两个线程并发执行了如果你用的是linux来编译的,你再输入g指令后加上-lpthread就可以了还有什么不懂的你可以多找找pthread类的例子
⒀c语言如何编写一个简单的多线程程序
⒁这是一个多线程例子,里面只有两个线程,是生产者/消费者模式,已编译通过,注释很详细,xdxa如下:xdxaxdxa/*以生产者和消费者模型问题来阐述Linux线程的控制和通信你xdxa生产者线程将生产的产品送入缓冲区,消费者线程则从中取出产品。xdxa缓冲区有N个,是一个环形的缓冲池。xdxa*/xdxa#includexdxa#include
⒂xdxaxdxa#defineBUFFER_SIZExdxaxdxastructprodconsxdxa{xdxaintbuffer;xdxap-》readpos++;xdxaif(p-》readpos==BUFFER_SIZE)xdxap-》readpos=;xdxa/*设置缓冲区未满的条件变量*/xdxapthread_cond_signal(&p-》notfull);xdxapthread_mutex_unlock(&p-》lock);xdxareturndata;xdxa}xdxa/*测试:生产站线程将到的整数送入缓冲区,消费者线程从缓冲区中获取整数,两者都打印信息*/xdxa#defineOVER(-)xdxastructprodconsbuffer;xdxavoid*producer(void*data)xdxa{xdxaintn;xdxafor(n=;n《;n++)xdxa{xdxaprintf(“%d------》
⒃“,n);xdxaput(&buffer,n);xdxa}xdxaput(&buffer,OVER);xdxareturnNULL;xdxa}xdxavoid*consumer(void*data)xdxa{xdxaintd;xdxawhile()xdxa{xdxad=get(&buffer);xdxaif(d==OVER)xdxabreak;xdxaelsexdxaprintf(“-----》%d
⒄“,d);xdxa}xdxareturnNULL;xdxa}xdxaintmain()xdxa{xdxapthread_tth_p,th_c;xdxavoid*retval;xdxapthread_init(&buffer);xdxapthread_create(&th_p,NULL,producer,);xdxapthread_create(&th_c,NULL,consumer,);xdxa/*等待两个线程结束*/xdxapthread_join(th_p,&retval);xdxapthread_join(th_c,&retval);xdxareturn;xdxa}
⒅C语言如何实现多线程同时运行
⒆点击菜单栏的“Project”选项卡,下拉列表的最后一项“Projectoptions...”是对当前工程的的属性进行设置的。
⒇选择弹出对话框中的“piler”选项卡。
⒈将其中的“RuntimeLibrary”的选择改为“Multithreaded(LIB)”。
⒉将看到对话框最下面的文本框中发生了一些变化,新增了“-MT”选项,这与编译器一开始所报的错误提示给出的解决方案一致。
⒊页面的设置完成后,再对该源码进行编译时,就能愉快地看到编译完全成功。
⒋c语言多线程编程,创建四个线程,依次往一个charstr[]型全局数组中写字符A,B,C,D
⒌#include?“stdio.h“#include?“process.h“#include?“stdlib.h“#include?“windows.h“//个全局事件变量,用于控制写入顺序HANDLE?event,event,event,event;int?count=;//计数变量char?str={};//void?thread(LPVOID?param){?while(TRUE)?{??WaitForSingleObject(event,INFINITE);??if(count》=)//??{???SetEvent(event);???break;??}??str=’A’;??SetEvent(event);?}}void?thread(LPVOID?param){?while(TRUE)?{??WaitForSingleObject(event,INFINITE);??if(count》=)//??{???SetEvent(event);???break;??}??str=’B’;??SetEvent(event);?}}void?thread(LPVOID?param){?while(TRUE)?{??WaitForSingleObject(event,INFINITE);??if(count》=)//??{???SetEvent(event);???break;??}??str=’C’;??SetEvent(event);?}}void?thread(LPVOID?param){?while(TRUE)?{??WaitForSingleObject(event,INFINITE);??if(count》=)//??{???SetEvent(event);???break;??}??str=’D’;??SetEvent(event);?}?_endthread();}//void?main(){?HANDLE?hthread;?event=CreateEvent(NULL,FALSE,FALSE,NULL);?event=CreateEvent(NULL,FALSE,FALSE,NULL);?event=CreateEvent(NULL,FALSE,FALSE,NULL);?event=CreateEvent(NULL,FALSE,FALSE,NULL);?hthread=(HANDLE)_beginthread(thread,,NULL);?hthread=(HANDLE)_beginthread(thread,,NULL);?hthread=(HANDLE)_beginthread(thread,,NULL);?hthread=(HANDLE)_beginthread(thread,,NULL);?SetEvent(event);?WaitForMultipleObjects(,hthread,TRUE,INFINITE);?printf(“%s
⒍用C语言写多线程程序
⒎thread_creation.cgthread_creation.c会在当前目录下,生成可执行的a.out文件
⒏c语言多线程套接字编程
⒐#include《stdlib.h》#include《stdio.h》#include《errno.h》#include《string.h》#include《sys/types.h》#include《i/in.h》#include《sys/wait.h》#include《sys/socket.h》#definePORT//Theportwhichismunicatewithserver#defineBACKLOG#defineLENGTH//Bufferlengthintmain(){intsockfd;//Socketfiledescriptorintnsockfd;//NewSocketfiledescriptorintnum;intsin_size;//tostorestructsizecharsdbuf;//Sendbufferstructsockaddr_inaddr_local;structsockaddr_inaddr_remote;charsendstr={“abcde“};/*GettheSocketfiledescriptor*/if((sockfd=socket(AF_I,SOCK_STREAM,))==-){printf(“ERROR:FailedtoobtainSocketDespcritor.
⒑“);return();}else{printf(“OK:ObtainSocketDespcritorsucessfully.
⒒“);}/*Fillthelocalsocketaddressstruct*/addr_local.sin_family=AF_I;//ProtocolFamilyaddr_local.sin_port=htons(PORT);//Portnumberaddr_local.sin_addr.s_addr=INADDR_ANY;//AutoFilllocaladdressbzero(&(addr_local.sin_zero),);//Flushtherestofstruct/*BlindaspecialPort*/if(bind(sockfd,(structsockaddr*)&addr_local,sizeof(structsockaddr))==-){printf(“ERROR:FailedtobindPort%d.
⒓“,PORT);return();}else{printf(“OK:BindthePort%dsucessfully.
⒔“,PORT);}/*Listenremoteconnect/calling*/if(listen(sockfd,BACKLOG)==-){printf(“ERROR:FailedtolistenPort%d.
⒕“,PORT);return();}else{printf(“OK:ListeningthePort%dsucessfully.
⒖“,PORT);}while(){sin_size=sizeof(structsockaddr_in);/*Waitaconnection,andobtainanewsocketfiledespriptorforsingleconnection*/if((nsockfd=aept(sockfd,(structsockaddr*)&addr_remote,&sin_size))==-){printf(“ERROR:ObtainnewSocketDespcritorerror.
⒗“);continue;}else{printf(“OK:Serverhasgotconnectfrom%s.
⒘“,i_ntoa(addr_remote.sin_addr));}/*Childprocess*/if(!fork()){printf(“Youcanenterstring,andpress’exit’toendtheconnect.
⒙“);while(strcmp(sdbuf,“exit“)!=){scanf(“%s“,sdbuf);if((num=send(nsockfd,sdbuf,strlen(sdbuf),))==-){printf(“ERROR:Failedtosentstring.
⒚“);close(nsockfd);exit();}printf(“OK:Sent%dbytessucessful,pleaseenteragain.
⒛“,num);}}close(nsockfd);while(waitpid(-,NULL,WNOHANG)》);}}