在线二区人妖系列_国产亚洲欧美日韩在线一区_国产一级婬片视频免费看_精品少妇一区二区三区在线

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

多線程

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

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

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

C++ 不包含對多線程應(yīng)用程序的任何嵌入式支持。相反,它完全依賴于操作系統(tǒ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)建一個 POSIX 線程:

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

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

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

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

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

終止線程

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

    #include <pthread.h>
    pthread_exit (status)

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

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

例子

下面簡單的樣例代碼,用 pthread_create() 函數(shù)創(chuàng)建了 5 個線程。每個線程均打印 “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í)行上面的程序,將會產(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ù)給線程

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

下面的例子解釋了這一點:

    #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í)行后,將會有以下的結(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

連接和分離線程

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

    pthread_join (threadid, status) 
    pthread_detach (threadid) 

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

下面的例子演示了如何使用 pthread_join 函數(shù)來等待一個線程結(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.