• <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。通過(guò)調(diào)用pthread_self()函數(shù)可以獲得自身的線程號(hào)。

             

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

             

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

             

                   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);

             

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

             

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

             

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

             

            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庫(kù)中,所以在編譯命令中需要將該庫(kù)導(dǎo)入。命令如下:

             

            gcc –o createthread –lpthread createthread.c

             

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

             

            下面一個(gè)問(wèn)題和前面創(chuàng)建進(jìn)程類似,不過(guò)帶來(lái)的問(wèn)題回避進(jìn)程要嚴(yán)重得多。如果你的主線程,也就是main函數(shù)執(zhí)行的那個(gè)線程,在你其他縣城推出之前就已經(jīng)退出,那么帶來(lái)的bug則不可估量。通過(guò)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;

             

            }

             

             

            下面說(shuō)一下前面提到的線程屬性。

             

            在我們前面提到,可以通過(guò)pthread_join()函數(shù)來(lái)使主線程阻塞等待其他線程退 出,這樣主線程可以清理其他線程的環(huán)境。但是還有一些線程,更喜歡自己來(lái)清理退出的狀態(tài),他們也不愿意主線程調(diào)用pthread_join來(lái)等待他們。我 們將這一類線程的屬性稱為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ì)有任何效果。

             

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

             

            int pthread_cancel(pthread_t thread);

             

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

             

            當(dāng)然,線程也不是被動(dòng)的被別人結(jié)束。它可以通過(guò)設(shè)置自身的屬性來(lái)決定如何結(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é)。

             

            通過(guò)調(diào)用pthread_setcanceltype()來(lái)設(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ù)是用來(lái)設(shè)置終結(jié)狀態(tài)的。還可以通過(guò)下面的函數(shù)來(lái)設(shè)置終結(jié)類型,即該線程可不可以被終結(jié):

             

            int pthread_setcancelstate(int state, int *oldstate);

             

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

             

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


            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
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(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)論排行榜

            无码人妻久久久一区二区三区| 久久精品夜夜夜夜夜久久| 久久99九九国产免费看小说| 男女久久久国产一区二区三区| 国产高潮国产高潮久久久91| 久久精品a亚洲国产v高清不卡| 久久久无码精品午夜| 国产精品一区二区久久精品| 2021国内精品久久久久久影院| 国产精品xxxx国产喷水亚洲国产精品无码久久一区| 亚洲精品无码久久久久AV麻豆| 伊人丁香狠狠色综合久久| 久久夜色精品国产欧美乱| 亚洲午夜无码AV毛片久久| 韩国三级中文字幕hd久久精品| 999久久久免费精品国产| 中文字幕乱码久久午夜| 亚洲国产成人精品无码久久久久久综合 | 伊人久久大香线蕉AV一区二区| 久久精品国产99国产电影网| 午夜人妻久久久久久久久| 久久久久久久久久久精品尤物 | 亚洲国产精品成人AV无码久久综合影院 | 狠狠综合久久综合88亚洲| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲中文字幕久久精品无码APP| 久久这里只有精品视频99| 久久99精品久久久久久不卡| 久久er国产精品免费观看2| www久久久天天com| 久久99精品久久久久久久久久| 中文字幕无码精品亚洲资源网久久| 亚洲欧美国产日韩综合久久| 久久乐国产精品亚洲综合| 久久精品国产72国产精福利| 99热热久久这里只有精品68| 久久亚洲精品视频| 色综合久久综合网观看| 久久国产视频99电影| 性做久久久久久免费观看| 性做久久久久久久久浪潮|