一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Linux多線程編程的基本的函數(shù)

 angelbrian 2011-07-19
函數(shù)原型:                  

#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg);

    返回值:若是成功建立線程返回0,否則返回錯誤的編號
    形式參數(shù):
                pthread_t *restrict tidp 要創(chuàng)建的線程的線程id指針
                const pthread_attr_t *restrict attr 創(chuàng)建線程時的線程屬性
                void* (start_rtn)(void) 返回值是void類型的指針函數(shù)
                vodi *restrict arg   start_rtn的行參
   例題1:
       功能:測試建立一個新的線程
       程序名稱: pthread_test.c      

#include <pthread.h>
#include <stdio.h>
void *create(void *arg)
...{
    printf("new thread created ..... ");
    
}
int main(int argc,char *argv[])
...{
    pthread_t tidp;
    int error;

    error=pthread_create(&tidp,NULL,create,NULL);
    if(error!=0)
    ......{
        printf("pthread_create is not created ... ");
        return -1;
    }
    printf("prthread_create is created... ");
    return 0;
}

     編譯方法:

#gcc -Wall -lpthread pthread_test.c

    因為pthread的庫不是linux系統(tǒng)的庫,所以在進(jìn)行編 譯的時候要加上-lpthread,否則編譯不過,會出現(xiàn)下面錯誤

thread_test.c: 在函 數(shù) ‘create’ 中:
thread_test.c:7: 警告: 在 有返回值的函數(shù)中,程序流程到達(dá)函數(shù)尾
/tmp/ccOBJmuD.o: In function `main':thread_test.c:(.text+0x4f):對 ‘pthread_create’未定義的引用
collect2: ld 返回 1

現(xiàn)在我們能建立了一個線程了,我們可以從函數(shù)的原型看到,在創(chuàng)建線程的時候,是可以在對 我們的函數(shù)進(jìn)行傳遞參數(shù),在pthread_create的第四個行參。我們看一下例題2~3.
    例題2

    功能:向新的線程傳遞整形值
    程序名稱:pthread_int.c   

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *create(void *arg)
...{
    int *num;
    num=(int *)arg;
    printf("create parameter is %d  ",*num);
    return (void *)0;
}
int main(int argc ,char *argv[])
...{
    pthread_t tidp;
    int error;
    
    int test=4;
    int *attr=&test;
    
    error=pthread_create(&tidp,NULL,create,(void *)attr);

    if(error!=0)
    ...{
        printf("pthread_create is created is not created ... ");
        return -1;
    }
    sleep(1);
    printf("pthread_create is created is  created ... ");
    return 0;
}

    編譯方法:

gcc -lpthread thread_int.c -Wall

    執(zhí)行結(jié)果:

create parameter is 4
pthread_create is created is  created ...

    例題總結(jié):
    可以看出來,我們在main函數(shù)中傳遞的整行指針,傳遞到我們新建的線程函數(shù)中。
    在上面的例子可以看出來我們向新的線程傳入了另一個線程的int數(shù)據(jù),線程之間還可以傳遞字符串或是更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

    例題3:
    程序功能:向新建的線程傳遞字符串
    程序名稱:thread_char.c   

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *create(void *arg)
...{
    char *name;
    name=(char *)arg;
    printf("arg is %s  ",name);
    return (void *)0;
}
int main(int argc,char *argv[])
...{
    char *a="wang";
    int error;
    pthread_t tidp;

    error=pthread_create(&tidp,NULL,create,(void *)a);

    if(error!=0)
    ...{
        printf("pthread is not created  ");
        return -1;
    }
    sleep(1);
    printf("pthread is created... ");
    return 0;
}    


    編譯方法:

gcc -Wall thread_char.c -lpthread


    執(zhí)行結(jié)果:

arg is wang
pthread is created...


    例題總結(jié):
    可以看出來main函數(shù)中的字符串傳入了新建里的線程中。

    例題4
    程序名稱:thread_struct.c   

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h> /**//*malloc()*/
struct test
...{
    int a;
    char *s;
};

void *create(void *arg)
...{
    struct test *temp;
    temp=(struct test *)arg;
    printf("test->a ==%d  ",temp->a);
    printf("test->s ==%s  ",temp->s);
    return (void *)0;
}
int main(int argc,char *argv[])
...{
    pthread_t tidp;
    int error;
    struct test *b;
    b=(struct test *)malloc(sizeof(struct test));
    b->a=4;
    b->s="wang";

    error=pthread_create(&tidp,NULL,create,(void *)b);

    if(error!=0)
    ...{
        printf("phread is not created... ");
        return -1;
    }
    sleep(1);
    printf("pthread is created... ");
    return 0;
}


    編譯方法:

gcc -Wall -lpthread thread_struct.c


    執(zhí)行結(jié)果:

test->a ==4
test->s ==wang
pthread is created...

線程包含了標(biāo)識進(jìn)程內(nèi)執(zhí)行環(huán)境必須的信息。他集成了進(jìn)程中的所有信息都是對線程進(jìn)行共享 的,包括文本程序、程序的全局內(nèi)存和堆內(nèi)存、棧以及文件描述符。

    例題5
    程序目的:驗證新建立的線程可以共享進(jìn)程中的數(shù)據(jù)
    程序名稱:thread_share.c   

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
static int a=4;
void *create(void *arg)
...{
    printf("new pthread ... ");
    printf("a==%d  ",a);
    return (void *)0;
}
int main(int argc,char *argv[])
...{
    pthread_t tidp;
    int error;
    a=5;

    error=pthread_create(&tidp,NULL,create,NULL);

    if(error!=0)
    ...{
        printf("new thread is not create ... ");
        return -1;
    }
    sleep(1);
    printf("new thread is created ... ");
    return 0;
}


    編譯方法:

gcc -Wall -lpthread thread_share.c


    執(zhí)行結(jié)果:

new pthread ...
a==5
new thread is created ...

   
    例題總結(jié):可以看出來,我們在主線程更改了我們的全局變量a的值的時候,我們新建立的線程則打印出來了改變的值,可以看出可以訪問線程所在進(jìn)程中的數(shù)據(jù)信 息。  
如果進(jìn)程中任何一個線程中調(diào)用exit,_Exit,或者是_exit,那么整個進(jìn)程就 會終止,與此類似,如果信號的默認(rèn)的動作是終止進(jìn)程,那么,把該信號發(fā)送到線程會終止進(jìn)程。
    線程的正常退出的方式:
       (1) 線程只是從啟動例程中返回,返回值是線程中的退出碼
       (2) 線程可以被另一個進(jìn)程進(jìn)行終止
       (3) 線程自己調(diào)用pthread_exit函數(shù)
    兩個重要的函數(shù)原型:  

#include <pthread.h>
void pthread_exit(void *rval_ptr);
/*rval_ptr 線程退出返回 的指針*/

int pthread_join(pthread_t thread,void **rval_ptr);
   /*成功結(jié)束進(jìn)程為0,否則為錯誤編碼*/

    例題6
    程序目的:線程正常退出,接受線程退出的返回碼
    程序名稱:exit_return.c   

   #include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *create(void *arg)
...{
    printf("new thread is created ... ");
    return (void *)2;
}
int main(int argc,char *argv[])
...{
    pthread_t tid;
    int error;
    void *temp;

    error=pthread_create(&tid,NULL,create,NULL);

    if(error!=0)
    ...{
        printf("thread is not created ... ");
        return -1;
    }
    error=pthread_join(tid,&temp);

    if(error!=0)
    ...{
        printf("thread is not exit ... ");
        return -2;
    }
    printf("thread is exit code %d  ",(int )temp);
    sleep(1);
    printf("thread is created... ");
    return 0;
}


    編譯方法:

gcc -Wall exit_return.c -lpthread


    執(zhí)行結(jié)果:

new thread is created ...
thread is exit code 2
thread is created...


    線程退出不僅僅可以返回線程的int數(shù)值,還可以返回一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
    例題7
    程序目的:線程結(jié)束返回一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
    程序名稱:exit_thread.c   

   #include <stdio.h>
#include <pthread.h>
#include <unistd.h>
struct test
...{
    int a;
    char *b;
};

struct test temp=
...{
    .a    =4,
    .b    ="wang"
};

void *create(void *arg)
...{
    printf("new thread ... ");
    return (void *)&temp;
}

int main(int argc,char *argv[])
...{
    int error;
    pthread_t tid;
    struct test *c;

    error=pthread_create(&tid,NULL,create,NULL);
    
    if(error!=0)
    ...{
        printf("new thread is not created ... ");
        return -1;
    }
    printf("main ... ");

    error=pthread_join(tid,(void *)&c);

    if(error!=0)
    ...{
        printf("new thread is not exit ... ");
        return -2;
    }
    printf("c->a ==%d  ",c->a);
    printf("c->b ==%s  ",c->b);
    sleep(1);
    return 0;
}


    編譯方法:
 

gcc -Wall -lpthread exit_struct.c

   
    執(zhí)行結(jié)果:

main ...
new thread ...
c->a ==4
c->b ==wang


    例題總結(jié):一定要記得返回的數(shù)據(jù)結(jié)構(gòu)要是在這個數(shù)據(jù)要返回的結(jié)構(gòu)沒有釋放的時候應(yīng)用,如果數(shù)據(jù)結(jié)構(gòu)已經(jīng)發(fā)生變化,那返回的就不會是我們所需要的,而是藏數(shù) 據(jù)阿。

函數(shù)原型:
   
#include <pthread.h>
pthread_t pthread_self(void);

    例題8
    程序目的:實(shí)現(xiàn)在新建立的線程中打印該線程的id和進(jìn)程id
    程序名稱:thread_self.c
   
#include <stdio.h>
#include <pthread.h>
#include <unistd.h> /**//*getpid()*/
void *create(void *arg)
...{
    printf("new thread .... ");
    printf("thread_tid==%u  ",(unsigned int)pthread_self());
    printf("thread pid is %d  ",getpid());
    return (void *)0;
}
int main(int argc,char *argv[])
...{
    pthread_t tid;
    int error;

    printf("Main thread is starting ... ");

    error=pthread_create(&tid,NULL,create,NULL);

    if(error!=0)
    ...{
        printf("thread is not created ... ");
        return -1;
    }
    printf("main pid is %d  ",getpid());
    sleep(1);
    return 0;
}


    編譯方法:

   
gcc -Wall -lpthread thread_self.c

    執(zhí)行結(jié)果:

Main thread is starting ...
main pid is 6860
new thread ....
thread_tid==3084954544
thread pid is 6860

   4、 線程的處理程序

    函數(shù)原型:   

#include <pthread.h>
void pthread_cleanup_push(void (*rtn)(void *),void *arg);
    函數(shù)rtn是清理函數(shù),arg是調(diào)用參數(shù)

void pthread_cleanup_pop(int execute);

    在前面講過線程的終止方式,是正常終止還是非正常終止,都會存在一個資源釋放的問題,在posix中提供了一組,就是我們上面看的函數(shù)進(jìn)行線程退出的處理 函數(shù),有些像在進(jìn)程中的atexit函數(shù)。釋放的方式是指pthread_cleanup_push的調(diào)用點(diǎn)到pthread_cleanup_pop之 間程序段進(jìn)行終止。

pthread_cleanup_push()/pthread_cleanup_pop采用先入后出的方式的棧的管理方式,void *rtn(void *),在執(zhí)行pthread_cleanup_push()時壓入函數(shù)棧,多次執(zhí)行pthread_cleanup_push()形成一個函數(shù)鏈,在執(zhí)行 這個函數(shù)鏈的時候會以反方向彈出,即先入后出。execute參數(shù)表識,是否執(zhí)行彈出清理函數(shù),當(dāng)execute=0時不進(jìn)行彈出清理函數(shù),非零的時候彈 出處理函數(shù)。

    例題9

    程序目的:實(shí)現(xiàn)在正常結(jié)束線程的時候,進(jìn)行函數(shù)處理

    程序名稱:thread_clean.c

    編譯方法:

    執(zhí)行結(jié)果: 

thread 1 start
thread 1 push complete
thread 1 exit code 1
thread 2 start
thread 2 push complete
cleanup :thread 2 second handler
cleanup :thread 2 first handler
thread 2 exit code 2

 gcc -Wall -lpthread thread_clean.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *clean(void *arg)
...{
    printf("cleanup :%s  ",(char *)arg);
    return (void *)0;
}
void *thr_fn1(void *arg)
...{
    printf("thread 1 start  ");
    pthread_cleanup_push(clean,"thread 1 first handler");
    pthread_cleanup_push(clean,"thread 1 second hadler");
    printf("thread 1 push complete  ");
    if(arg)
    ...{
        return((void *)1);
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    return (void *)1;
}
void *thr_fn2(void *arg)
...{
    printf("thread 2 start  ");
    pthread_cleanup_push(clean,"thread 2 first handler");
    pthread_cleanup_push(clean,"thread 2 second handler");
    printf("thread 2 push complete  ");
    if(arg)
    ...{
        pthread_exit((void *)2);
    }
    pthread_cleanup_pop(0);
    pthread_cleanup_pop(0);
    pthread_exit((void *)2);
}
int main(void)
...{
    int err;
    pthread_t tid1,tid2;
    void *tret;

    err=pthread_create(&tid1,NULL,thr_fn1,(void *)1);
    if(err!=0)
    ...{
        printf("error .... ");
        return -1;
    }
    err=pthread_create(&tid2,NULL,thr_fn2,(void *)1);

    if(err!=0)
    ...{
        printf("error .... ");
        return -1;
    }
    err=pthread_join(tid1,&tret);
    if(err!=0)
    ...{
        printf("error .... ");
        return -1;
    }
    printf("thread 1 exit code %d  ",(int)tret);

    err=pthread_join(tid2,&tret);
    if(err!=0)
    ...{
        printf("error .... ");
        return -1;
    }
 gcc -Wall -lpthread thread_clean.c

    printf("thread 2 exit code %d  ",(int)tret);
    exit(0);
}


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲做性视频在线播放| 日韩色婷婷综合在线观看| 性感少妇无套内射在线视频| 伊人久久青草地综合婷婷| 日本成人三级在线播放 | 在线视频三区日本精品| 东京热男人的天堂一二三区| 国产精品久久男人的天堂| 成人免费在线视频大香蕉| 国产精品一区二区三区激情| 国产精品日韩精品最新| 国产又粗又猛又大爽又黄| 内射精品欧美一区二区三区久久久| 亚洲国产av精品一区二区| 婷婷色香五月综合激激情| 五月天丁香婷婷一区二区| 无套内射美女视频免费在线观看| 国产又色又粗又黄又爽| 人人妻人人澡人人夜夜| 久久99热成人网不卡| 欧美日韩精品视频在线| 国产一区二区三区丝袜不卡| 国产av一区二区三区四区五区| 日韩精品一区二区一牛| 日本加勒比在线观看不卡| 国产又粗又猛又爽色噜噜| 人妻熟女欲求不满一区二区| 亚洲国产精品一区二区| 久久国产亚洲精品成人| 欧美日韩乱码一区二区三区| 亚洲一区二区三区一区| 精品人妻一区二区三区免费看| 欧美精品久久男人的天堂| 日韩精品日韩激情日韩综合| 国产欧美日韩综合精品二区| 日韩综合国产欧美一区| 日韩人妻精品免费一区二区三区 | 久久精品欧美一区二区三不卡| 好吊妞在线免费观看视频| 久久re6热在线视频| 精品老司机视频在线观看|