• <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使一個(gè)線程等待另一個(gè)線程結(jié)束。

             

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

             

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

             

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

             

            通過創(chuàng)建線程,線程將會(huì)執(zhí)行一個(gè)線程函數(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);

             

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

             

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

             

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

             

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

             

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

             

            下面是一個(gè)簡(jiǎn)單的創(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;

             

            }

             

             

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

             

            gcc –o createthread –lpthread createthread.c

             

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

             

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

             

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

             

            thread:等待退出線程的線程號(hào)。

             

            value_ptr:退出線程的返回值。

             

            下面一個(gè)例子結(jié)合上面的內(nèi)容:

             

            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),他們也不愿意主線程調(diào)用pthread_join來等待他們。我 們將這一類線程的屬性稱為detached。如果我們?cè)谡{(diào)用pthread_create()函數(shù)的時(shí)候?qū)傩栽O(shè)置為NULL,則表明我們希望所創(chuàng)建的線 程采用默認(rèn)的屬性,也就是jionable。如果需要將屬性設(shè)置為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);

             

            }

             

             

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

             

            線程可以通過自身執(zhí)行結(jié)束來結(jié)束,也可以通過調(diào)用pthread_exit()來結(jié)束線程的執(zhí)行。另外,線程甲可以被線程乙被動(dòng)結(jié)束。這個(gè)通過調(diào)用pthread_cancel()來達(dá)到目的。

             

            int pthread_cancel(pthread_t thread);

             

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

             

            當(dāng)然,線程也不是被動(dòng)的被別人結(jié)束。它可以通過設(shè)置自身的屬性來決定如何結(jié)束。

             

            線程的被動(dòng)結(jié)束分為兩種,一種是異步終結(jié),另外一種是同步終結(jié)。異步終結(jié)就是當(dāng)其他線程調(diào)用 pthread_cancel的時(shí)候,線程就立刻被結(jié)束。而同步終結(jié)則不會(huì)立刻終結(jié),它會(huì)繼續(xù)運(yùn)行,直到到達(dá)下一個(gè)結(jié)束點(diǎn)(cancellation point)。當(dāng)一個(gè)線程被按照默認(rèn)的創(chuàng)建方式創(chuàng)建,那么它的屬性是同步終結(jié)。

             

            通過調(diào)用pthread_setcanceltype()來設(shè)置終結(jié)狀態(tài)。

             

            int pthread_setcanceltype(int type, int *oldtype);

             

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

             

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

             

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

             

            int pthread_setcancelstate(int state, int *oldstate);

             

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

             

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


            from:

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

            posted on 2010-08-24 18:01 chatler 閱讀(2633) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Linux_Coding
            <2010年2月>
            31123456
            78910111213
            14151617181920
            21222324252627
            28123456
            78910111213

            常用鏈接

            留言簿(10)

            隨筆分類(307)

            隨筆檔案(297)

            algorithm

            Books_Free_Online

            C++

            database

            Linux

            Linux shell

            linux socket

            misce

            • cloudward
            • 感覺這個(gè)博客還是不錯(cuò),雖然做的東西和我不大相關(guān),覺得看看還是有好處的

            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

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            亚洲AV日韩AV天堂久久| 综合久久给合久久狠狠狠97色| 久久天天躁狠狠躁夜夜avapp| 欧美大香线蕉线伊人久久| 东京热TOKYO综合久久精品| 久久九九有精品国产23百花影院| 久久精品一区二区国产| 久久露脸国产精品| 久久精品国产久精国产一老狼| 国内精品久久久久久99蜜桃| 国产激情久久久久影院| 77777亚洲午夜久久多人| 久久99国产精品久久99| 一级做a爰片久久毛片看看| 久久久久亚洲AV无码专区体验| 999久久久免费国产精品播放| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 亚洲愉拍99热成人精品热久久| 国内精品久久久久久久97牛牛| 久久青青草原精品国产软件| 久久久久人妻一区精品色| 久久综合色之久久综合| 99久久久精品免费观看国产| 中文字幕无码久久精品青草| 国产一久久香蕉国产线看观看| 午夜视频久久久久一区 | 久久天天躁狠狠躁夜夜avapp | 久久香蕉国产线看观看乱码| 亚洲欧美国产精品专区久久| 热re99久久精品国产99热| 少妇久久久久久久久久| 性做久久久久久久久老女人| 久久精品国产精品亚洲精品| 亚洲va久久久噜噜噜久久天堂| 久久午夜综合久久| 91精品国产91久久| 久久国产高潮流白浆免费观看| 久久国产欧美日韩精品免费| 国内精品久久久久久久亚洲| 精品免费tv久久久久久久| 新狼窝色AV性久久久久久|