亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1515 | 回復(fù): 2
打印 上一主題 下一主題

Linux下多線程編程詳解 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2007-10-25 12:31 |只看該作者 |倒序瀏覽

線程(thread)技術(shù)早在60年代就被提出,但真正應(yīng)用多線程到操作系統(tǒng)中去,是在80年代中期,solaris是這方面的佼佼者。傳統(tǒng)的Unix也支持線程的概念,但是在一個進(jìn)程(process)中只允許有一個線程,這樣多線程就意味著多進(jìn)程。
現(xiàn)在,多線程技術(shù)已經(jīng)被許多操作系統(tǒng)所支持,包括Windows/NT,當(dāng)然,也包括Linux。
  為什么有了進(jìn)程的概念后,還要再引入線程呢?使用多線程到底有哪些好處?什么的系統(tǒng)應(yīng)該選用多線程?我們首先必須回答這些問題。
  使用多線程的理由之一是和進(jìn)程相比,它是一種非常"節(jié)儉"的多任務(wù)操作方式。我們知道,在Linux系統(tǒng)下,啟動一個新的進(jìn)程必須分配給它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來維護(hù)它的代碼段、堆棧段和數(shù)據(jù)段,這是一種"昂貴"的多任務(wù)工作方式。而運(yùn)行于一個進(jìn)程中的多個線程,它們彼此之間使用相同的地址空間,共享大部分?jǐn)?shù)據(jù),啟動一個線程所花費(fèi)的空間遠(yuǎn)遠(yuǎn)小于啟動一個進(jìn)程所花費(fèi)的空間,而且,線程間彼此切換所需的時間也遠(yuǎn)遠(yuǎn)小于進(jìn)程間切換所需要的時間。據(jù)統(tǒng)計,總的說來,一個進(jìn)程的開銷大約是一個線程開銷的30倍左右,當(dāng)然,在具體的系統(tǒng)上,這個數(shù)據(jù)可能會有較大的區(qū)別。
  使用多線程的理由之二是線程間方便的通信機(jī)制。對不同進(jìn)程來說,它們具有獨(dú)立的數(shù)據(jù)空間,要進(jìn)行數(shù)據(jù)的傳遞只能通過通信的方式進(jìn)行,這種方式不僅費(fèi)時,而且很不方便。線程則不然,由于同一進(jìn)程下的線程之間共享數(shù)據(jù)空間,所以一個線程的數(shù)據(jù)可以直接為其它線程所用,這不僅快捷,而且方便。當(dāng)然,數(shù)據(jù)的共享也帶來其他一些問題,有的變量不能同時被兩個線程所修改,有的子程序中聲明為static的數(shù)據(jù)更有可能給多線程程序帶來災(zāi)難性的打擊,這些正是編寫多線程程序時最需要注意的地方。
  除了以上所說的優(yōu)點(diǎn)外,不和進(jìn)程比較,多線程程序作為一種多任務(wù)、并發(fā)的工作方式,當(dāng)然有以下的優(yōu)點(diǎn):
  1) 提高應(yīng)用程序響應(yīng)。這對圖形界面的程序尤其有意義,當(dāng)一個操作耗時很長時,整個系統(tǒng)都會等待這個操作,此時程序不會響應(yīng)鍵盤、鼠標(biāo)、菜單的操作,而使用多線程技術(shù),將耗時長的操作(time consuming)置于一個新的線程,可以避免這種尷尬的情況。
  2) 使多CPU系統(tǒng)更加有效。操作系統(tǒng)會保證當(dāng)線程數(shù)不大于CPU數(shù)目時,不同的線程運(yùn)行于不同的CPU上。
  3) 改善程序結(jié)構(gòu)。一個既長又復(fù)雜的進(jìn)程可以考慮分為多個線程,成為幾個獨(dú)立或半獨(dú)立的運(yùn)行部分,這樣的程序會利于理解和修改。
  下面我們先來嘗試編寫一個簡單的多線程程序。
  簡單的多線程編程
  Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為pthread。編寫Linux下的多線程程序,需要使用頭文件pthread.h,連接時需要使用庫libpthread.a。順便說一下,Linux下pthread的實(shí)現(xiàn)是通過系統(tǒng)調(diào)用clone()來實(shí)現(xiàn)的。clone()是Linux所特有的系統(tǒng)調(diào)用,它的使用方式類似fork,關(guān)于clone()的詳細(xì)情況,有興趣的讀者可以去查看有關(guān)文檔說明。下面我們展示一個最簡單的多線程程序 pthread_create.c。
一個重要的線程創(chuàng)建函數(shù)原型:
#include
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ù)
                void *restrict arg   start_rtn的行參
               
例程1:                                
    功能:創(chuàng)建一個簡單的線程
    程序名稱:pthread_create.c         
/********************************************************************************************
**    Name:pthread_create.c
**    Used to study the multithread programming in Linux OS
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
void *myThread1(void)
{
    int i;
    for (i=0; i
#include
#include
void *create(void *arg)
{
    int *num;
    num=(int *)arg;
    printf("create parameter is %d \n",*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)
        {
        printf("pthread_create is created is not created ... \n");
        return -1;
        }
    sleep(1);
    printf("pthread_create is created ...\n");
    return 0;        
}
    編譯方法:
gcc -lpthread pthread_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:
    程序功能:向新建的線程傳遞字符串
        程序名稱:pthread_string.c
/********************************************************************************************
**    Name:pthread_string.c
**    Used to study the multithread programming in Linux OS
**    Pass a ‘char*‘ parameter to the thread.
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
#include
void *create(void *arg)
{
    char *name;
    name=(char *)arg;
    printf("The parameter passed from main function is %s  \n",name);
    return (void *)0;
}
int main(int argc, char *argv[])
{
    char *a="zieckey";
    int error;
    pthread_t tidp;
    error=pthread_create(&tidp, NULL, create, (void *)a);
    if(error!=0)
    {
        printf("pthread is not created.\n");
        return -1;
    }
    sleep(1);
    printf("pthread is created... \n");
    return 0;
}   
  編譯方法:
gcc -Wall pthread_string.c -lpthread
    執(zhí)行結(jié)果:
The parameter passed from main function is zieckey  
pthread is created...
    例程總結(jié):
    可以看出來main函數(shù)中的字符串傳入了新建的線程中。
例程4:
    程序功能:向新建的線程傳遞字符串
        程序名稱:pthread_struct.c
/********************************************************************************************
**    Name:pthread_struct.c
**    Used to study the multithread programming in Linux OS
**    Pass a ‘char*‘ parameter to the thread.
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
#include
#include
struct menber
{
    int a;
    char *s;
};
void *create(void *arg)
{
    struct menber *temp;
    temp=(struct menber *)arg;
    printf("menber->a = %d  \n",temp->a);
    printf("menber->s = %s  \n",temp->s);
    return (void *)0;
}
int main(int argc,char *argv[])
{
    pthread_t tidp;
    int error;
    struct menber *b;
    b=(struct menber *)malloc( sizeof(struct menber) );
    b->a = 4;
    b->s = "zieckey";
    error = pthread_create(&tidp, NULL, create, (void *)b);
    if( error )
    {
        printf("phread is not created...\n");
        return -1;
    }
    sleep(1);
    printf("pthread is created...\n");
    return 0;
}
  編譯方法:
gcc -Wall pthread_struct.c -lpthread
    執(zhí)行結(jié)果:
menber->a = 4  
menber->s = zieckey  
pthread is created...
    例程總結(jié):
    可以看出來main函數(shù)中的一個結(jié)構(gòu)體傳入了新建的線程中。
    線程包含了標(biāo)識進(jìn)程內(nèi)執(zhí)行環(huán)境必須的信息。他集成了進(jìn)程中的所有信息都是對線程進(jìn)行共享的,包括文本程序、程序的全局內(nèi)存和堆內(nèi)存、棧以及文件描述符。
   
例程5:
    程序目的:驗證新建立的線程可以共享進(jìn)程中的數(shù)據(jù)
    程序名稱:pthread_share.c  
/********************************************************************************************
**    Name:pthread_share_data.c
**    Used to study the multithread programming in Linux OS
**    Pass a ‘char*‘ parameter to the thread.
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
#include
static int a=4;
void *create(void *arg)
{
    printf("new pthread ... \n");
    printf("a=%d  \n",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 ... \n");
        return -1;
    }
   
    sleep(1);
   
    printf("new thread is created ... \n");
    return 0;
}
   
  編譯方法:
gcc -Wall pthread_share_data.c -lpthread
    執(zhí)行結(jié)果:
new pthread ...
a=5  
new thread is created ...
    例程總結(jié):
可以看出來,我們在主線程更改了我們的全局變量a的值的時候,我們新建立的線程則打印出來了改變的值,可以看出可以訪問線程所在進(jìn)程中的數(shù)據(jù)信息。
         2、線程的終止
    如果進(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
void pthread_exit(void *rval_ptr);
/*rval_ptr 線程退出返回的指針*/
int pthread_join(pthread_t thread,void **rval_ptr);
   /*成功結(jié)束進(jìn)程為0,否則為錯誤編碼*/
    例程6
    程序目的:線程正常退出,接受線程退出的返回碼
    程序名稱:pthread_exit.c
/********************************************************************************************
**    Name:pthread_exit.c
**    Used to study the multithread programming in Linux OS
**    A example showing a thread to exit and with a return code.
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
#include
void *create(void *arg)
{
    printf("new thread is created ... \n");
    return (void *)8;
}
int main(int argc,char *argv[])
{
    pthread_t tid;
    int error;
    void *temp;
    error = pthread_create(&tid, NULL, create, NULL);
    if( error )
    {
        printf("thread is not created ... \n");
        return -1;
    }
    error = pthread_join(tid, &temp);
    if( error )
    {
        printf("thread is not exit ... \n");
        return -2;
    }
   
    printf("thread is exit code %d \n", (int )temp);
    return 0;
}
  編譯方法:
gcc -Wall pthread_exit.c -lpthread
    執(zhí)行結(jié)果:
new thread is created ...
thread is exit code 8
    例程總結(jié):
可以看出來,線程退出可以返回線程的int數(shù)值。線程退出不僅僅可以返回線程的int數(shù)值,還可以返回一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
    例程7
    程序目的:線程結(jié)束返回一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
    程序名稱:pthread_return_struct.c
#include
#include
#include
struct menber
{
    int a;
    char *b;
}temp={8,"zieckey"};
void *create(void *arg)
{
    printf("new thread ... \n");
    return (void *)&temp;
}
int main(int argc,char *argv[])
{
    int error;
    pthread_t tid;
    struct menber *c;
    error = pthread_create(&tid, NULL, create, NULL);
   
    if( error )
    {
        printf("new thread is not created ... \n");
        return -1;
    }
    printf("main ... \n");
    error = pthread_join(tid,(void *)&c);
    if( error )
    {
        printf("new thread is not exit ... \n");
        return -2;
    }
    printf("c->a = %d  \n",c->a);
    printf("c->b = %s  \n",c->b);
    sleep(1);
    return 0;
}
  編譯方法:
gcc -Wall pthread_return_struct.c -lpthread
    執(zhí)行結(jié)果:
main ...
new thread ...
c->a = 8
c->b = zieckey
例程總結(jié):
一定要記得返回的數(shù)據(jù)結(jié)構(gòu)要是在這個數(shù)據(jù)要返回的結(jié)構(gòu)沒有釋放的時候應(yīng)用,
如果數(shù)據(jù)結(jié)構(gòu)已經(jīng)發(fā)生變化,那返回的就不會是我們所需要的,而是臟數(shù)據(jù)
3、線程標(biāo)識
    函數(shù)原型:
   
#include
pthread_t pthread_self(void);
pid_t getpid(void);
    getpid()用來取得目前進(jìn)程的進(jìn)程識別碼,函數(shù)說明
    例程8
    程序目的:實(shí)現(xiàn)在新建立的線程中打印該線程的id和進(jìn)程id
    程序名稱:pthread_id.c
   
/********************************************************************************************
**    Name:pthread_id.c
**    Used to study the multithread programming in Linux OS.
**    Showing how to get the thread's tid and the process's pid.
**    Author:zeickey
**    Date:2006/9/16        
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/
#include
#include
#include  /*getpid()*/
void *create(void *arg)
{
    printf("New thread .... \n");
    printf("This thread's id is %u  \n", (unsigned int)pthread_self());
    printf("The process pid is %d  \n",getpid());
    return (void *)0;
}
int main(int argc,char *argv[])
{
    pthread_t tid;
    int error;
    printf("Main thread is starting ... \n");
    error = pthread_create(&tid, NULL, create, NULL);
    if(error)
    {
        printf("thread is not created ... \n");
        return -1;
    }
    printf("The main process's pid is %d  \n",getpid());
    sleep(1);
    return 0;
}
    編譯方法:
   
gcc -Wall -lpthread pthread_id.c
    執(zhí)行結(jié)果:
Main thread is starting ...
The main process's pid is 3307  
New thread ....
This thread's id is 3086347152  
The process pid is 3307  
原文地址
http://www.yuanma.org/data/2007/0921/article_2859.htm

本文轉(zhuǎn)自:
http://blog.chinaunix.net/u/25975/showart_402864.htm



本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u1/38279/showart_407329.html

論壇徽章:
0
2 [報告]
發(fā)表于 2014-06-24 09:40 |只看該作者
對于初學(xué)者來說用處非常大,謝謝 LZ的分享。。頂

論壇徽章:
0
3 [報告]
發(fā)表于 2014-09-11 17:36 |只看該作者
謝謝樓主的分享。。。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP