• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 297,  comments - 15,  trackbacks - 0

            pthread_join函數(shù)及linux線程

            pthread_join使一個線程等待另一個線程結束。

             

            代碼中如果沒有pthread_join主線程會很快結束從而使整個進程結束,從而使創(chuàng)建的線程沒有機會開始執(zhí)行就結束了。加入pthread_join后,主線程會一直等待直到等待的線程結束自己才結束,使創(chuàng)建的線程有機會執(zhí)行。

             

            所有線程都有一個線程號,也就是Thread ID。其類型為pthread_t。通過調用pthread_self()函數(shù)可以獲得自身的線程號。

             

            下面說一下如何創(chuàng)建一個線程。

             

            通過創(chuàng)建線程,線程將會執(zhí)行一個線程函數(shù),該線程格式必須按照下面來聲明:

             

                   void * Thread_Function(void *)

             

            創(chuàng)建線程的函數(shù)如下:

             

                   int pthread_create(pthread_t *restrict thread,

             

                          const pthread_attr_t *restrict attr,

             

                          void *(*start_routine)(void*), void *restrict arg);

             

            下面說明一下各個參數(shù)的含義:

             

            thread:所創(chuàng)建的線程號。

             

            attr:所創(chuàng)建的線程屬性,這個將在后面詳細說明。

             

            start_routine:即將運行的線程函數(shù)。

             

            art:傳遞給線程函數(shù)的參數(shù)。

             

            下面是一個簡單的創(chuàng)建線程例子:

             

            #include <pthread.h>

             

            #include <stdio.h>

             

            /* Prints x’s to stderr. The parameter is unused. Does not return. */

             

            void* print_xs (void* unused)

             

            {

             

            while (1)

             

            fputc (‘x’, stderr);

             

            return NULL;

             

            }

             

            /* The main program. */

             

            int main ()

             

            {

             

            pthread_t thread_id;

             

            /* Create a new thread. The new thread will run the print_xs

             

            function. */

             

            pthread_create (&thread_id, NULL, &print_xs, NULL);

             

            /* Print o’s continuously to stderr. */

             

            while (1)

             

            fputc (‘o’, stderr);

             

            return 0;

             

            }

             

             

            在編譯的時候需要注意,由于線程創(chuàng)建函數(shù)在libpthread.so庫中,所以在編譯命令中需要將該庫導入。命令如下:

             

            gcc –o createthread –lpthread createthread.c

             

            如果想傳遞參數(shù)給線程函數(shù),可以通過其參數(shù)arg,其類型是void *。如果你需要傳遞多個參數(shù)的話,可以考慮將這些參數(shù)組成一個結構體來傳遞。另外,由于類型是void *,所以你的參數(shù)不可以被提前釋放掉。

             

            下面一個問題和前面創(chuàng)建進程類似,不過帶來的問題回避進程要嚴重得多。如果你的主線程,也就是main函數(shù)執(zhí)行的那個線程,在你其他縣城推出之前就已經退出,那么帶來的bug則不可估量。通過pthread_join函數(shù)會讓主線程阻塞,直到所有線程都已經退出。

             

            int pthread_join(pthread_t thread, void **value_ptr);

             

            thread:等待退出線程的線程號。

             

            value_ptr:退出線程的返回值。

             

            下面一個例子結合上面的內容:

             

            int main ()

             

            {

             

            pthread_t thread1_id;

             

            pthread_t thread2_id;

             

            struct char_print_parms thread1_args;

             

            struct char_print_parms thread2_args;

             

            /* Create a new thread to print 30,000 x’s. */

             

            thread1_args.character = ’x’;

             

            thread1_args.count = 30000;

             

            pthread_create (&thread1_id, NULL, &char_print, &thread1_args);

             

            /* Create a new thread to print 20,000 o’s. */

             

            thread2_args.character = ’o’;

             

            thread2_args.count = 20000;

             

            pthread_create (&thread2_id, NULL, &char_print, &thread2_args);

             

            /* Make sure the first thread has finished. */

             

            pthread_join (thread1_id, NULL);

             

            /* Make sure the second thread has finished. */

             

            pthread_join (thread2_id, NULL);

             

            /* Now we can safely return. */

             

            return 0;

             

            }

             

             

            下面說一下前面提到的線程屬性。

             

            在我們前面提到,可以通過pthread_join()函數(shù)來使主線程阻塞等待其他線程退 出,這樣主線程可以清理其他線程的環(huán)境。但是還有一些線程,更喜歡自己來清理退出的狀態(tài),他們也不愿意主線程調用pthread_join來等待他們。我 們將這一類線程的屬性稱為detached。如果我們在調用pthread_create()函數(shù)的時候將屬性設置為NULL,則表明我們希望所創(chuàng)建的線 程采用默認的屬性,也就是jionable。如果需要將屬性設置為detached,則參考下面的例子:

             

            #include <stdio.h>

             

            #include <pthread.h>

             

            void * start_run(void * arg)

             

            {

             

                    //do some work

             

            }

             

            int main()

             

            {

             

                    pthread_t thread_id;

             

                    pthread_attr_t attr;

             

                    pthread_attr_init(&attr);

             

                    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

             

                    pthread_create(&thread_id,&attr,start_run,NULL);

             

                    pthread_attr_destroy(&attr);

             

                    sleep(5);

             

                    exit(0);

             

            }

             

             

            在線程設置為joinable后,可以調用pthread_detach()使之成為detached。但是相反的操作則不可以。還有,如果線程已經調用pthread_join()后,則再調用pthread_detach()則不會有任何效果。

             

            線程可以通過自身執(zhí)行結束來結束,也可以通過調用pthread_exit()來結束線程的執(zhí)行。另外,線程甲可以被線程乙被動結束。這個通過調用pthread_cancel()來達到目的。

             

            int pthread_cancel(pthread_t thread);

             

                   函數(shù)調用成功返回0

             

            當然,線程也不是被動的被別人結束。它可以通過設置自身的屬性來決定如何結束。

             

            線程的被動結束分為兩種,一種是異步終結,另外一種是同步終結。異步終結就是當其他線程調用 pthread_cancel的時候,線程就立刻被結束。而同步終結則不會立刻終結,它會繼續(xù)運行,直到到達下一個結束點(cancellation point)。當一個線程被按照默認的創(chuàng)建方式創(chuàng)建,那么它的屬性是同步終結。

             

            通過調用pthread_setcanceltype()來設置終結狀態(tài)。

             

            int pthread_setcanceltype(int type, int *oldtype);

             

            state:要設置的狀態(tài),可以為PTHREAD_CANCEL_DEFERRED或者為PTHREAD_CANCEL_ASYNCHRONOUS

             

            那么前面提到的結束點又是如何設置了?最常用的創(chuàng)建終結點就是調用pthread_testcancel()的地方。該函數(shù)除了檢查同步終結時的狀態(tài),其他什么也不做。

             

            上面一個函數(shù)是用來設置終結狀態(tài)的。還可以通過下面的函數(shù)來設置終結類型,即該線程可不可以被終結:

             

            int pthread_setcancelstate(int state, int *oldstate);

             

                   state:終結狀態(tài),可以為PTHREAD_CANCEL_DISABLE或者PTHREAD_CANCEL_ENABLE。具體什么含義大家可以通過單詞意思即可明白。

             

            最后說一下線程的本質。其實在Linux中,新建的線程并不是在原先的進程中,而是系統(tǒng)通過 一個系統(tǒng)調用clone()。該系統(tǒng)copy了一個和原先進程完全一樣的進程,并在這個進程中執(zhí)行線程函數(shù)。不過這個copy過程和fork不一樣。 copy后的進程和原先的進程共享了所有的變量,運行環(huán)境。這樣,原先進程中的變量變動在copy后的進程中便能體現(xiàn)出來。


            from:

            http://blog.csdn.net/jxxfqyy/archive/2009/04/16/4084193.aspx

            posted on 2010-08-24 18:01 chatler 閱讀(2633) 評論(0)  編輯 收藏 引用 所屬分類: Linux_Coding
            <2011年5月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個博客還是不錯,雖然做的東西和我不大相關,覺得看看還是有好處的

            network

            OSS

            • Google Android
            • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
            • os161 file list

            overall

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久久受www免费人成| 久久性精品| 久久99精品国产麻豆| 亚洲国产成人久久精品99| 青青草原1769久久免费播放| 亚洲日本va中文字幕久久| 美女久久久久久| 久久99热只有频精品8| 精品久久久无码中文字幕| 天天爽天天爽天天片a久久网| 日本国产精品久久| 久久九九久精品国产免费直播| 国产精品一区二区久久精品| 999久久久免费精品国产| 成人免费网站久久久| 亚洲中文字幕伊人久久无码| 青青热久久综合网伊人| 少妇久久久久久久久久| 国产成人精品白浆久久69| 亚洲天堂久久久| 中文字幕热久久久久久久| 久久福利片| 99久久国产热无码精品免费久久久久 | 久久人人爽人人爽人人片AV高清 | 久久亚洲国产欧洲精品一| 超级碰碰碰碰97久久久久| 亚洲国产精品一区二区久久hs| 久久99热这里只有精品国产| 久久国产一区二区| 久久99热只有频精品8| 久久久女人与动物群交毛片| 99国内精品久久久久久久| 国产欧美一区二区久久| 久久91精品久久91综合| 久久99国产亚洲高清观看首页| 漂亮人妻被黑人久久精品| 久久久久久极精品久久久 | 韩国免费A级毛片久久| 久久久久国产精品熟女影院| 男女久久久国产一区二区三区| 国产成人久久精品一区二区三区|