• <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>
            隨筆 - 70, 文章 - 0, 評(píng)論 - 9, 引用 - 0
            數(shù)據(jù)加載中……

            可重入函數(shù)(reentrant function)

            原文地址:http://blog.chinaunix.net/space.php?uid=20491906&do=blog&cuid=322733

            由于cublog系統(tǒng)的緣故,將前段時(shí)間寫的一篇blog文章再次貼上。


            可重入函數(shù)這一概念早有接觸,但一直未有系統(tǒng)的理解,最近閱讀《APUE》信號(hào)一章時(shí),其中講解很到位,故總結(jié)如下。

            信號(hào)作為一種軟中斷,能夠被進(jìn)程給捕獲,因而也就中斷進(jìn)程的正常執(zhí)行,轉(zhuǎn)而去執(zhí)行信號(hào)處理程序,最后再返回到原進(jìn)程繼續(xù)正常執(zhí)行。然而,當(dāng)進(jìn)程正在執(zhí)行malloc()動(dòng)態(tài)內(nèi)存分配時(shí),信號(hào)產(chǎn)生從而轉(zhuǎn)入到信號(hào)處理程序,但當(dāng)信號(hào)處理程序中也用到了malloc()函數(shù)時(shí),問題就出來了?因?yàn)?/span>malloc()通常維護(hù)一個(gè)所有已分配內(nèi)存鏈表,當(dāng)信號(hào)發(fā)生時(shí),進(jìn)程可能正在修改鏈表指針,這時(shí)在信號(hào)處理程序中將又一次修改鏈表。當(dāng)然類似的情況還有不少,下文中將會(huì)談到。
             

            因此,在進(jìn)行上層應(yīng)用程序設(shè)計(jì)過程中我們就必須明確哪些函數(shù)是可重入性函數(shù)(reentrant functions)。可重入性函數(shù)通常也一定能夠在信號(hào)處理程序(signal handler)中被調(diào)用。
             

            1 能夠在信號(hào)處理程序中調(diào)用的可重入性函數(shù)(節(jié)自《APUE》)

            accept

            fchmod

            lseek

            sendto

            stat

            access

            fchown

            lstat

            setgid

            symlink

            aio_error

            fcntl

            mkdir

            setpgid

            sysconf

            aio_return

            fdatasync

            mkfifo

            setsid

            tcdrain

            aio_suspend

            fork

            open

            setsockopt

            tcflow

            alarm

            fpathconf

            pathconf

            setuid

            tcflush

            bind

            fstat

            pause

            shutdown

            tcgetattr

            cfgetispeed

            fsync

            pipe

            sigaction

            tcgetpgrp

            cfgetospeed

            ftruncate

            poll

            sigaddset

            tcsendbreak

            cfsetispeed

            getegid

            posix_trace_event

            sigdelset

            tcsetattr

            cfsetospeed

            geteuid

            pselect

            sigemptyset

            tcsetpgrp

            chdir

            getgid

            raise

            sigfillset

            time

            chmod

            getgroups

            read

            sigismember

            timer_getoverrun

            chown

            getpeername

            readlink

            signal

            timer_gettime

            clock_gettime

            getpgrp

            recv

            sigpause

            timer_settime

            close

            getpid

            recvfrom

            sigpending

            times

            connect

            getppid

            recvmsg

            sigprocmask

            umask

            creat

            getsockname

            rename

            sigqueue

            uname

            dup

            getsockopt

            rmdir

            sigset

            unlink

            dup2

            getuid

            select

            sigsuspend

            utime

            execle

            kill

            sem_post

            sleep

            wait

            execve

            link

            send

            socket

            waitpid

            _Exit & _exit

            listen

            sendmsg

            socketpair

            write

             

            縱觀上表,我們可以看出,有不少系統(tǒng)調(diào)用函數(shù)并沒有出現(xiàn),換言之也就是非可重入性函數(shù)。函數(shù)不可重入的原因主要如下:

            <!--[if !supportLists]-->(1)       <!--[endif]-->函數(shù)使用了static靜態(tài)數(shù)據(jù)結(jié)構(gòu)

            如:struct passwd *getpwuid(uid_t uid);

            struct passwd *getpwnam(const char *name);

            struct passwd *getpwent(void);

            以上3個(gè)函數(shù)都是返回一個(gè)指向passwd結(jié)構(gòu)的指針,而該passwd結(jié)構(gòu)通常都是函數(shù)中static變量,其內(nèi)容在每次調(diào)用以上函數(shù)時(shí)都會(huì)被重寫。因此,當(dāng)進(jìn)程主程序與信號(hào)處理程序中均調(diào)用了以上函數(shù)時(shí),沖突就產(chǎn)生了。

            <!--[if !supportLists]-->(2)       <!--[endif]-->函數(shù)調(diào)用了mallocfree函數(shù),正如文章最開始所提到的;

            <!--[if !supportLists]-->(3)       <!--[endif]-->函數(shù)為標(biāo)準(zhǔn)I/O的庫函數(shù),因?yàn)榇蠖鄶?shù)的標(biāo)準(zhǔn)I/O庫函數(shù)的實(shí)現(xiàn)都使用了global全局?jǐn)?shù)據(jù)結(jié)構(gòu);

            因此,若要寫可重入性函數(shù)的做法通常是我們?cè)诤瘮?shù)中只修改局部變量,而不改變?nèi)肿兞浚虮M量不使用全局變量、靜態(tài)static變量。

            事實(shí)上,與可重入性函數(shù)(reentrant function)對(duì)應(yīng)的還有可重入內(nèi)核(reentrant kernel),其區(qū)別和聯(lián)系在《深入理解Linux內(nèi)核》上有較詳細(xì)的講解。



            posted on 2011-07-18 09:56 seahouse 閱讀(995) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 技術(shù)概念

            99久久人人爽亚洲精品美女 | 久久人妻少妇嫩草AV无码专区| 精品久久久久久久久久中文字幕 | 国产精品亚洲美女久久久| 久久亚洲欧美国产精品| 久久婷婷五月综合成人D啪| 一级做a爰片久久毛片看看| 伊人久久大香线蕉AV色婷婷色| 久久精品国产免费观看三人同眠| 日韩av无码久久精品免费| 久久精品国产精品青草app| 精品国产青草久久久久福利| 亚洲精品蜜桃久久久久久| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 国产成人99久久亚洲综合精品| 久久性生大片免费观看性| 国产69精品久久久久9999APGF | 91精品无码久久久久久五月天| 色青青草原桃花久久综合| 青青青国产成人久久111网站| 国产精品一区二区久久精品涩爱| 国产精品99久久久久久人| 欧美精品国产综合久久| yellow中文字幕久久网| 久久精品国产亚洲av麻豆色欲| 精品人妻伦九区久久AAA片69| 久久久久久久97| 久久久久久久久久久| 性欧美大战久久久久久久| 26uuu久久五月天| 国产精品美女久久久m| 中文字幕日本人妻久久久免费| 久久精品国产亚洲5555| 国产成人久久精品麻豆一区| 国产精品99精品久久免费| 久久婷婷激情综合色综合俺也去| 亚洲精品99久久久久中文字幕| 久久久久久国产精品美女| 久久国产精品一区| 色欲综合久久躁天天躁| 久久精品极品盛宴观看|