c++多线程问题 c++多线程问题?

C++\u591a\u7ebf\u7a0b\u5f00\u53d1\uff1a\u4e00\uff0c\u4e3a\u4ec0\u4e48\u6211\u4eec\u8981\u4f7f\u7528\u591a\u7ebf\u7a0b

\u591a\u7ebf\u7a0b\u7684\u4f7f\u7528\u4e3b\u8981\u662f\u7528\u6765\u5904\u7406\u7a0b\u5e8f\u201c\u5728\u4e00\u90e8\u5206\u4e0a\u4f1a\u963b\u585e\u201d\uff0c\u201c\u5728\u53e6\u4e00\u90e8\u5206\u4e0a\u9700\u8981\u6301\u7eed\u8fd0\u884c\u201d\u7684\u573a\u5408\u3002\u4e00\u822c\u662f\u6839\u636e\u9700\u6c42\uff0c\u53ef\u4ee5\u7528\u591a\u7ebf\u7a0b\uff0c\u4e8b\u4ef6\u89e6\u53d1\uff0ccallback\u7b49\u65b9\u6cd5\u8fbe\u5230\u3002\u4f46\u662f\u6709\u4e00\u4e9b\u65b9\u6cd5\u662f\u53ea\u6709\u591a\u7ebf\u7a0b\u80fd\u529e\u5230\u7684\u5c31\u53ea\u6709\u7528\u591a\u7ebf\u7a0b\u6216\u8005\u591a\u8fdb\u7a0b\u6765\u5b8c\u6210\u3002
\u4e3e\u4e2a\u7b80\u5355\u7684\u4f8b\u5b50\uff0c\u80fd\u7406\u89e3\u5c31\u884c\u3002\u5047\u8bbe\u6709\u8fd9\u6837\u4e00\u4e2a\u7a0b\u5e8f\uff0c
1\u4f1a\u4e0d\u505c\u7684\u5904\u7406\u6536\u5230\u7684\u6240\u6709TCP\u8bf7\u6c42\u3002\u5bf9\u4e8e\u6bcf\u4e2aTCP\u8bf7\u6c42\u505a\u4e0d\u540c\u7684\u64cd\u4f5c\u3002\u4e0d\u80fd\u6709\u9057\u6f0f
2\u6709\u5f88\u591a\u7279\u5b9a\u7684\u8bf7\u6c42\u4f1a\u5411\u4e00\u4e2a\u670d\u52a1\u5668\u53d1\u9001\u5b58\u50a8\u7684\u6570\u636e\uff0c\u6216\u8005\u662f\u7b49\u5f85\u7528\u6237\u8f93\u5165\u3002

\u6211\u4eec\u6765\u770b\u770b\u3002\u7b2c1\u4e2a\u8981\u6c42\u5f88\u7b80\u5355\u3002\u7528\u4e2awhile\u5faa\u73af\u5c31\u641e\u5b9a\u4e86\u3002\u4f46\u7b2c2\u4e2a\u7279\u6027\u5462\u3002\u4e00\u65e6\u5728\u7b49\u5f85\u7528\u6237\u8f93\u5165\u6216\u8005\u662f\u8fde\u63a5\u670d\u52a1\u5668\u65f6\uff0c\u7a0b\u5e8f\u4f1a\u201c\u963b\u585e\u201d\u4e00\u6bb5\u65f6\u95f4\uff0c\u8fd9\u4e00\u6bb5\u65f6\u95f4\u5185\u5c31\u65e0\u6cd5\u5904\u7406\u5176\u4ed6\u7684TCP\u8bf7\u6c42\u4e86\u3002
\u6240\u4ee5\u53ef\u4ee5\u5229\u7528\u591a\u7ebf\u7a0b\uff0c\u6bcf\u4e2a\u7ebf\u7a0b\u5904\u7406\u4e0d\u540c\u7684TCP\u8bf7\u6c42\u3002\u8fd9\u6837\u7a0b\u5e8f\u5c31\u4e0d\u4f1a\u201c\u963b\u585e\u201d\u6389\u4e86\u3002

C++\u662f\u4e00\u79cd\u9762\u5411\u5bf9\u8c61\u7684\u8ba1\u7b97\u673a\u7a0b\u5e8f\u8bbe\u8ba1\u8bed\u8a00\uff0c\u7531\u7f8e\u56fdAT&T\u8d1d\u5c14\u5b9e\u9a8c\u5ba4\u7684\u672c\u8d3e\u5c3c\u00b7\u65af\u7279\u52b3\u65af\u7279\u5362\u666e\u535a\u58eb\u572820\u4e16\u7eaa80\u5e74\u4ee3\u521d\u671f\u53d1\u660e\u5e76\u5b9e\u73b0\uff0c\u6700\u521d\u5b83\u88ab\u79f0\u4f5c\u201cC with Classes\u201d\u3002\u5b83\u662f\u4e00\u79cd\u9759\u6001\u6570\u636e\u7c7b\u578b\u68c0\u67e5\u7684\u3001\u652f\u6301\u591a\u91cd\u7f16\u7a0b\u8303\u5f0f\u7684\u901a\u7528\u7a0b\u5e8f\u8bbe\u8ba1\u8bed\u8a00\uff0c\u652f\u6301\u8fc7\u7a0b\u5316\u7a0b\u5e8f\u8bbe\u8ba1\u3001\u6570\u636e\u62bd\u8c61\u3001\u9762\u5411\u5bf9\u8c61\u7a0b\u5e8f\u8bbe\u8ba1\u3001\u6cdb\u578b\u7a0b\u5e8f\u8bbe\u8ba1\u7b49\u591a\u79cd\u7a0b\u5e8f\u8bbe\u8ba1\u98ce\u683c.C++\u662fC\u8bed\u8a00\u7684\u7ee7\u627f\uff0c\u8fdb\u4e00\u6b65\u6269\u5145\u548c\u5b8c\u5584\u4e86C\u8bed\u8a00\uff0c\u6210\u4e3a\u4e00\u79cd\u9762\u5411\u5bf9\u8c61\u7684\u7a0b\u5e8f\u8bbe\u8ba1\u8bed\u8a00\u3002

  当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。

CCriticalSection类的用法非常简单,步骤如下:
 

定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如CCriticalSection critical_section;
在访问需要保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象: critical_section.Lock();

在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线程占有临界区对象,则调用Lock()的线程获得临界区;否则,线程将被挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。
访问临界区完毕后,使用CCriticalSection的成员函数Unlock()来释放临界区:critical_section.Unlock();

再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会继续执行。

临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。

下面通过一段代码展示了临界区在保护多线程访问的共享资源中的作用。通过两个线程来分别对全局变量g_cArray[10]进行写入操作,用临界区结构对象g_cs来保持线程的同步,并在开启线程前对其进行初始化。为了使实验效果更加明显,体现出临界区的作用,在线程函数对共享资源g_cArray[10]的写入时,以Sleep()函数延迟1毫秒,使其他线程同其抢占CPU的可能性增大。如果不使用临界区对其进行保护,则共享资源数据将被破坏,而使用临界区对线程保持同步后则可以得到正确的结果。代码实现清单附下:

// 临界区结构对象
CRITICAL_SECTION g_cs;
// 共享资源
char g_cArray[10];
UINT ThreadProc10(LPVOID pParam)
{
 // 进入临界区
 EnterCriticalSection(&g_cs);
 // 对共享资源进行写入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[i] = ''a'';
  Sleep(1);
 }
 // 离开临界区
 LeaveCriticalSection(&g_cs);
 return 0;
}
UINT ThreadProc11(LPVOID pParam)
{
 // 进入临界区
 EnterCriticalSection(&g_cs);
 // 对共享资源进行写入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[10 - i - 1] = ''b'';
  Sleep(1);
 }
 // 离开临界区
 LeaveCriticalSection(&g_cs);
 return 0;
}
……
void CSample08View::OnCriticalSection()
{
 // 初始化临界区
 InitializeCriticalSection(&g_cs);
 // 启动线程
 AfxBeginThread(ThreadProc10, NULL);
 AfxBeginThread(ThreadProc11, NULL);
 // 等待计算完毕
 Sleep(300);
 // 报告计算结果
 CString sResult = CString(g_cArray);
 AfxMessageBox(sResult);
}

  在使用临界区时,一般不允许其运行时间过长,只要进入临界区的线程还没有离开,其他所有试图进入此临界区的线程都会被挂起而进入到等待状态,并会在一定程度上影响。程序的运行性能。尤其需要注意的是不要将等待用户输入或是其他一些外界干预的操作包含到临界区。如果进入了临界区却一直没有释放,同样也会引起其他线程的长时间等待。换句话说,在执行了EnterCriticalSection()语句进入临界区后无论发生什么,必须确保与之匹配的LeaveCriticalSection()都能够被执行到。可以通过添加结构化异常处理代码来确保LeaveCriticalSection()语句的执行。虽然临界区同步速度很快,但却只能用来同步本进程内的线程,而不可用来同步多个进程中的线程。

  MFC为临界区提供有一个CCriticalSection类,使用该类进行线程同步处理是非常简单的,只需在线程函数中用CCriticalSection类成员函数Lock()和UnLock()标定出被保护代码片段即可。对于上述代码,可通过CCriticalSection类将其改写如下:

// MFC临界区类对象
CCriticalSection g_clsCriticalSection;
// 共享资源
char g_cArray[10];
UINT ThreadProc20(LPVOID pParam)
{
 // 进入临界区
 g_clsCriticalSection.Lock();
 // 对共享资源进行写入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[i] = ''a'';
  Sleep(1);
 }
 // 离开临界区
 g_clsCriticalSection.Unlock();
 return 0;
}
UINT ThreadProc21(LPVOID pParam)
{
 // 进入临界区
 g_clsCriticalSection.Lock();
 // 对共享资源进行写入操作
 for (int i = 0; i < 10; i++)
 {
  g_cArray[10 - i - 1] = ''b'';
  Sleep(1);
 }
 // 离开临界区
 g_clsCriticalSection.Unlock();
 return 0;
}
……
void CSample08View::OnCriticalSectionMfc()
{
 // 启动线程
 AfxBeginThread(ThreadProc20, NULL);
 AfxBeginThread(ThreadProc21, NULL);
 // 等待计算完毕
 Sleep(300);
 // 报告计算结果
 CString sResult = CString(g_cArray);
 AfxMessageBox(sResult);
}

进程中的所有线程共享进程的虚拟地址空间,进程中的线程是并行执行的,系统为每个线程划分执行时间,

看下咱那个操作系统的书,上边哟了

  • c++澶氱嚎绋嬮棶棰
    绛旓細褰澶氫釜绾跨▼璁块棶涓涓嫭鍗犳у叡浜祫婧愭椂,鍙互浣跨敤鈥滀复鐣屽尯鈥濆璞°備换涓鏃跺埢鍙湁涓涓嚎绋嬪彲浠ユ嫢鏈変复鐣屽尯瀵硅薄锛屾嫢鏈変复鐣屽尯鐨勭嚎绋嬪彲浠ヨ闂淇濇姢璧锋潵鐨勮祫婧愭垨浠g爜娈碉紝鍏朵粬甯屾湜杩涘叆涓寸晫鍖虹殑绾跨▼灏嗚鎸傝捣绛夊緟锛岀洿鍒版嫢鏈変复鐣屽尯鐨勭嚎绋嬫斁寮冧复鐣屽尯鏃朵负姝紝杩欐牱灏变繚璇佷簡涓嶄細鍦ㄥ悓涓鏃跺埢鍑虹幇澶氫釜绾跨▼璁块棶鍏变韩璧勬簮銆侰CriticalSecti...
  • c璇█澶氱嚎绋绾跨▼涓嶆墽琛岀殑鍘熷洜
    绛旓細鏁呴殰鐜拌薄 浣跨敤澶氱嚎绋鐨勬椂鍊欙紝涓诲嚱鏁板皻涓旇繕鍦ㄦ墽琛岋紝浣嗗瓙鍑芥暟鍗翠笉鎵ц銆俰f __name__=='__main__':print('Parent process %s.' % os.getpid())p = Pool(processes = 4)for i in range(30):p.apply_async(func = stitch, args=(i,))print('Waiting for all subprocesses done...')p.c...
  • C/C++澶氱嚎绋嬮棶棰?
    绛旓細C璇█涓洿鎺ヨ皟鐢绾跨▼灏辨槸CreateThread(&thread_proc, ...)鍗冲彲 鍥犱负C++鐨勭被鏄湪杩愯闃舵鍒嗛厤鍦板潃锛岃屼笉鏄湪缂栬瘧闃舵鍒嗛厤鍦板潃锛屾墍浠ヨ鎯冲湪绫诲嚱鏁颁腑澹版槑绾跨▼锛屽氨蹇呴』寮哄埗鎶婄嚎绋嬫垚鍛樺嚱鏁拌缃负缂栬瘧闃舵灏卞垎閰嶅湴鍧锛岃繖鏍锋墠鑳界粦瀹氬埌WINDOWS API鐨凜reateThread鍑芥暟涓婂幓锛岃繖绉嶆柟寮忓彨鍋歴tatic.涔嬫墍浠ヤ繚瀛樼嚎绋嬫寚閽堟槸鍥犱负鐜...
  • 濡備綍鐢C璇█瀹炵幇澶氱嚎绋涓嬬敓浜ц呮秷璐硅呬簰鏂ュ悓姝闂
    绛旓細鐢熶骇鑰咃紝娑堣垂鑰呬簰鏂ュ悓姝ュ弬鑰冨涓嬩唬鐮侊細include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #include <error.h> #include <semaphore.h> #define PRODUCER_NUM 10 #define CONSUMER_MUM 8 #define BUFFER_SIZE 20 #define S...
  • 濡備綍鐢C璇█瀹炵幇澶氱嚎绋涓嬬敓浜ц呮秷璐硅呬簰鏂ュ悓姝闂
    绛旓細鍒欏彲浠ュ彇浜у搧锛屽惁鍒欐秷璐硅呯▼搴忔寕璧风瓑寰 //鍙栬蛋涓涓骇鍝佹搷浣 V(& empty);//閫氱煡鐢熶骇鑰呰繘绋嬪彲浠ョ敓浜 } //涓诲嚱鏁 void main(){ //鍒嗗埆璋冪敤鐢熶骇鑰咃紝娑堣垂鑰呯▼搴忥紝椤哄簭涓嶉檺锛屽洜涓哄凡缁忓畬鎴愪俊鍙烽噺鐨勫悓姝ワ紝鑻ュ彂鐢熷悓姝闂灏变細绛夊緟 producer()锛沜onsumer()锛沜onsumer()锛沺roducer()锛涒︹︹ ...
  • 鐢C璇█濡備綍瀹炵幇澶氱嚎绋鍚屾椂杩愯鐨勬儏鍐典笅,鍚勪釜绾跨▼杈撳嚭涓嶅悓鐨勯殢鏈烘暟...
    绛旓細1銆佷娇鐢╬thread搴撴墽琛澶氱嚎绋,杩欎釜鏄疞inux涓嬬殑绾跨▼搴 Windows涓嬪簲璇ユ湁鑷繁鐨凙PI,涓嶈繃杩欑涓滆タ涓鑸繕鏄互Linux涓烘爣鍑嗐俻thread_create()鍒涘缓涓涓嚎绋,浼犲叆fun()鐨勫嚱鏁版寚閽堝氨琛屼簡銆傜劧鍚庤繖涓狟eep()鐨勯渶姹傝杩涜绾跨▼闂撮氫俊,鍙互鐢ㄥ叡浜唴瀛樼殑鏂规硶,璁句竴涓猙ool鍙橀噺flag鍏变韩,鐒跺悗beep鐨勬椂鍊欒涓篺alse,beep瀹岃鎴恡rue銆俧un()...
  • c璇█windows涓嬪啓澶氱嚎绋鐨闂
    绛旓細"%d\n",pid);涔嬮棿鐨勯『搴忔槸鏈煡鐨勶紝瑙嗕綘鐨勭郴缁熺幆澧冭屽畾銆傛瘮濡傛垜杩愯浜嗗嚑娆★紝缁撴灉閮戒笉涓鏍凤紝鏈夋椂鍊欐槸鍙緭鍑5涓殢鏈烘暟锛屾湁鏃跺欏拰浣犵殑缁撴灉涓鏍枫傚鏋滃姞浜嗚冻澶熺殑sleep锛岄偅涔堝氨鍙互纭繚鍦ㄦ墽琛宲rintf("%d\n",pid);鍓嶏紝绾跨▼鍑芥暟宸茬粡缁撴潫浜嗭紝閭d箞灏变笉浼氬嚭鐜版贩涔辩殑缁撴灉浜嗐
  • [楂樺垎,鎬C璇█,濡備綍瀹炵幇澶氱嚎绋,鏈夊叿浣撴柟妗,璇锋彁渚!
    绛旓細浣犺繖涓闂鍙槸瓒呰繃200鍒嗙殑鍟婏紝杩欎釜寰澶т簡璇存槸涓涓瘮杈冨鏉傜殑璁捐鏂规銆傚疄闄呬笂C璇█鏄病鏈澶氱嚎绋鐨勬蹇电殑锛屼絾鏄垜浠彲浠ラ氳繃Task鏉ュ疄鐜板浠诲姟銆傜畝鍗曠殑璇达紝鍙互閲囧彇浠ヤ笅鏂规锛氬畾涔変竴涓富Task锛屽皢鍏剁疆涓哄父椹籘ask,鐢ㄤ互杩涜Task璋冨害鍜孴ask鐨勫惎鍔/缁堜簡鍜屼氦浜掔殑绠$悊銆傚畾涔変竴涓猅ask浼樺厛绾у垪琛紝鐢ㄤ紭鍏堢骇鏉ヤ綔涓...
  • C璇█ 澶氱嚎绋 骞跺彂鎵ц 涓嶉殢鏈
    绛旓細1锛歱thread_join鍜屽苟鍙戜笉骞跺彂娌″叧绯伙紝鏄寚绛夊緟瀛愮嚎绋嬬粨鏉熶箣鍚庢墠杩斿洖銆備綘鐨勪唬鐮佹湁涓涓闂锛屽氨鏄彧绛夊緟浜嗘渶鍚庝竴涓嚎绋嬬粨鏉燂紝浣犵殑pthread_join鐨勭涓涓弬鏁帮紝灏辨槸鏈鍚庝竴涓嚎绋嬬殑id銆備笉杩囪繖涓拰骞跺彂椤哄簭娌″叧绯 2锛氫綘鐨凜PU鏄笉鏄彧鏈1涓牳锛澶氱嚎绋鍙湁杩愯鍦ㄥ鏍窩PU鎵嶈兘鐪熸灏嗙嚎绋嬪垎閰嶇粰涓嶅悓CPU锛屽苟鍙戞墽琛...
  • C 璇█绾跨▼闂存庝箞閫氫俊?
    绛旓細C 璇█涓殑绾跨▼闂撮氫俊鏄浣曞疄鐜板苟浼樺寲鐨勶紵鍦–璇█鐨澶氱嚎绋缂栫▼涓紝鐞嗚В绾跨▼闂寸殑閫氫俊鏈哄埗鑷冲叧閲嶈銆傞鍏堬紝鎴戜滑闇瑕佹槑纭殑鏄紝鍚屼竴杩涚▼鍐呯殑绾跨▼闂撮氫俊閫氬父鏄棤缂濈殑锛屼絾涓轰簡淇濊瘉鏁版嵁瀹夊叏锛屾垜浠線寰闇瑕佷富鍔ㄥ紩鍏ユ満鍒舵潵闅旂涓嶅悓绾跨▼锛岄伩鍏嶆暟鎹薄鏌撳拰鑴忚鍐闂銆傝繖闇瑕佸鎿嶄綔绯荤粺搴曞眰鏈夋繁鍏ョ悊瑙o紝鍥犱负澶氱嚎绋嬪崗浣...
  • 扩展阅读:c++编程入门自学 ... c#多线程面试问题 ... c++多线程面试题及答案 ... c++怎么实现多线程 ... c++面试题 ... c++编程五年级题库100题 ... c++应届生面试题 ... c++网络编程面试题 ... c++ 多线程 输入 ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网