在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C/ 多線程
動(dòng)態(tài)內(nèi)存
類和對(duì)象
接口 (抽象類)
結(jié)構(gòu)體
循環(huán)的類型
函數(shù)
數(shù)字
日期和時(shí)間
基本語法
多態(tài)
數(shù)據(jù)抽象
注釋
命名空間
字符串
預(yù)處理器
決策語句
修飾符的類型
鍙橀噺綾誨瀷
基本輸入輸出
操作符
數(shù)組
模板
多線程
繼承
Web 編程
信號(hào)處理
指針
存儲(chǔ)類型
概述
引用
常量
異常處理
開發(fā)環(huán)境
重載
變量作用域
數(shù)據(jù)類型
數(shù)據(jù)封裝
文件和流

多線程

多線程是多任務(wù)處理的一種特殊形式,而多任務(wù)處理是一種讓你的電腦能并發(fā)運(yùn)行兩個(gè)或兩個(gè)以上程序的特性。一般有兩種類型的多任務(wù)處理:基于進(jìn)程的和基于線程的。

基于進(jìn)程的多任務(wù)處理是并發(fā)執(zhí)行的程序?;诰€程的多任務(wù)處理是并發(fā)執(zhí)行的程序的一部分。

多線程程序包含了可以并發(fā)運(yùn)行的兩個(gè)或更多個(gè)程序部分。這樣程序中的每個(gè)部分稱為一個(gè)線程,并且每個(gè)線程都定義了一個(gè)單獨(dú)的執(zhí)行路徑。

C++ 不包含對(duì)多線程應(yīng)用程序的任何嵌入式支持。相反,它完全依賴于操作系統(tǒng)來提供此項(xiàng)功能。

本教程假設(shè)您正在使用的是 Linux 操作系統(tǒng),我們將要使用 POSIX 編寫 C++ 多線程程序。 POSIX 線程,或稱 Pthreads,它提供了在許多類 Unix 的 POSIX 系統(tǒng)(如 FreeBSD,NetBSD,GNU/Linux,Mac OS X 和 Solaris)中可用的 API。

創(chuàng)建線程

我們使用下面的函數(shù)來創(chuàng)建一個(gè) POSIX 線程:

    #include <pthread.h>
    pthread_create (thread, attr, start_routine, arg)

這里的 pthread_create 創(chuàng)建了一個(gè)新線程,并使其可執(zhí)行。這個(gè)函數(shù)可以在代碼中的任意位置調(diào)用任意次。

下面是詳細(xì)的參數(shù)說明:

參數(shù) 描述
thread 新線程的不透明、唯一的標(biāo)識(shí)符,它由子函數(shù)返回。
attr 一個(gè)不透明的屬性對(duì)象,可用于設(shè)置線程屬性。你可以指定一個(gè)線程的屬性對(duì)象,默認(rèn)值為 NULL。
start_routine C++ 例程,線程一旦創(chuàng)建將會(huì)被執(zhí)行。
arg 一個(gè)傳遞給 start_routine 的參數(shù)。它必須傳遞一個(gè) void 類型指針的引用。如果沒有參數(shù)傳遞,默認(rèn)值為 NULL。

一個(gè)進(jìn)程可創(chuàng)建的最大線程數(shù)是依賴實(shí)現(xiàn)決定的。線程一旦創(chuàng)建,它們之間是對(duì)等的,而且也有可能創(chuàng)建其它的線程。線程之間沒有隱含的層次或依賴關(guān)系。

終止線程

我們使用下面的函數(shù)來終止一個(gè) POSIX 線程:

    #include <pthread.h>
    pthread_exit (status)

此處的 pthread_exit 用于顯式的退出一個(gè)線程。通常在線程已完成了其工作,并且沒有存在的必要的時(shí)候,調(diào)用 pthread_exit()函數(shù)。

如果 main()在其創(chuàng)建的線程之前終止,并且使用了 pthread_exit() 來退出線程,那么其線程將會(huì)繼續(xù)執(zhí)行。否則,當(dāng) main() 終止后,這些線程將會(huì)自動(dòng)終止。

例子

下面簡單的樣例代碼,用 pthread_create() 函數(shù)創(chuàng)建了 5 個(gè)線程。每個(gè)線程均打印 “Hello World!”,然后調(diào)用 pthread_exit() 函數(shù)終止了線程。

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>

    using namespace std;

    #define NUM_THREADS 5

    void *PrintHello(void *threadid)
    {
       long tid;
       tid = (long)threadid;
       cout << "Hello World! Thread ID, " << tid << endl;
       pthread_exit(NULL);
    }

    int main ()
    {
       pthread_t threads[NUM_THREADS];
       int rc;
       int i;
       for( i=0; i < NUM_THREADS; i++ ){
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, 
      PrintHello, (void *)i);
      if (rc){
     cout << "Error:unable to create thread," << rc << endl;
     exit(-1);
      }
       }
       pthread_exit(NULL);
    }

使用 -lpthread 庫編譯上面的程序,如下所示:

    $gcc test.cpp -lpthread

現(xiàn)在執(zhí)行上面的程序,將會(huì)產(chǎn)生如下的結(jié)果:

    main() : creating thread, 0
    main() : creating thread, 1
    main() : creating thread, 2
    main() : creating thread, 3
    main() : creating thread, 4
    Hello World! Thread ID, 0
    Hello World! Thread ID, 1
    Hello World! Thread ID, 2
    Hello World! Thread ID, 3
    Hello World! Thread ID, 4

傳遞參數(shù)給線程

下面的例子展示了如何通過一個(gè)結(jié)構(gòu)體傳遞多個(gè)參數(shù)。你可以在一個(gè)線程回調(diào)中傳遞任何數(shù)據(jù)類型,這是因?yàn)樗赶?void 類型。

下面的例子解釋了這一點(diǎn):

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>

    using namespace std;

    #define NUM_THREADS 5

    struct thread_data{
       int  thread_id;
       char *message;
    };

    void *PrintHello(void *threadarg)
    {
       struct thread_data *my_data;

       my_data = (struct thread_data *) threadarg;

       cout << "Thread ID : " << my_data->thread_id ;
       cout << " Message : " << my_data->message << endl;

       pthread_exit(NULL);
    }

    int main ()
    {
       pthread_t threads[NUM_THREADS];
       struct thread_data td[NUM_THREADS];
       int rc;
       int i;

       for( i=0; i < NUM_THREADS; i++ ){
      cout <<"main() : creating thread, " << i << endl;
      td[i].thread_id = i;
      td[i].message = "This is message";
      rc = pthread_create(&threads[i], NULL,
      PrintHello, (void *)&td[i]);
      if (rc){
     cout << "Error:unable to create thread," << rc << endl;
     exit(-1);
      }
       }
       pthread_exit(NULL);
    }

當(dāng)上述代碼編譯和執(zhí)行后,將會(huì)有以下的結(jié)果:

    main() : creating thread, 0
    main() : creating thread, 1
    main() : creating thread, 2
    main() : creating thread, 3
    main() : creating thread, 4
    Thread ID : 3 Message : This is message
    Thread ID : 2 Message : This is message
    Thread ID : 0 Message : This is message
    Thread ID : 1 Message : This is message
    Thread ID : 4 Message : This is message

連接和分離線程

下面的兩個(gè)函數(shù),我們可以用它們來連接或分離線程:

    pthread_join (threadid, status) 
    pthread_detach (threadid) 

pthread_join()子例程會(huì)阻塞調(diào)用它的線程,一直等到其指定的 threadid 的線程結(jié)束為止。當(dāng)一個(gè)線程創(chuàng)建后,它的屬性決定了它是否是可連接的或可分離的。只有創(chuàng)建時(shí)屬性為可連接的線程才可以連接。如果創(chuàng)建的是一個(gè)可分離的線程,那么它永遠(yuǎn)不能連接。

下面的例子演示了如何使用 pthread_join 函數(shù)來等待一個(gè)線程結(jié)束。

    #include <iostream>
    #include <cstdlib>
    #include <pthread.h>
    #include <unistd.h>

    using namespace std;

    #define NUM_THREADS 5

    void *wait(void *t)
    {
       int i;
       long tid;

       tid = (long)t;

       sleep(1);
       cout << "Sleeping in thread " << endl;
       cout << "Thread with id : " << tid << "  ...exiting " << endl;
       pthread_exit(NULL);
    }

    int main ()
    {
       int rc;
       int i;
       pthread_t threads[NUM_THREADS];
       pthread_attr_t attr;
       void *status;

       // Initialize and set thread joinable
       pthread_attr_init(&attr);
       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

       for( i=0; i < NUM_THREADS; i++ ){
      cout << "main() : creating thread, " << i << endl;
      rc = pthread_create(&threads[i], NULL, wait, &amp;&amp;i );
      if (rc){
     cout << "Error:unable to create thread," << rc << endl;
     exit(-1);
      }
       }

       // free attribute and wait for the other threads
       pthread_attr_destroy(&attr);
       for( i=0; i < NUM_THREADS; i++ ){
      rc = pthread_join(threads[i], &status);
      if (rc){
     cout << "Error:unable to join," << rc << endl;
     exit(-1);
      }
      cout << "Main: completed thread id :" << i ;
      cout << "  exiting with status :" << status << endl;
       }

       cout << "Main: program exiting." << endl;
       pthread_exit(NULL);
    }

當(dāng)上述代碼編譯和執(zhí)行后,將產(chǎn)生以下的結(jié)果:

    main() : creating thread, 0
    main() : creating thread, 1
    main() : creating thread, 2
    main() : creating thread, 3
    main() : creating thread, 4
    Sleeping in thread
    Thread with id : 0 .... exiting
    Sleeping in thread
    Thread with id : 1 .... exiting
    Sleeping in thread
    Thread with id : 2 .... exiting
    Sleeping in thread
    Thread with id : 3 .... exiting
    Sleeping in thread
    Thread with id : 4 .... exiting
    Main: completed thread id :0  exiting with status :0
    Main: completed thread id :1  exiting with status :0
    Main: completed thread id :2  exiting with status :0
    Main: completed thread id :3  exiting with status :0
    Main: completed thread id :4  exiting with status :0
    Main: program exiting.