1. 程式人生 > >Linux下多執行緒(pthread)程式設計例項

Linux下多執行緒(pthread)程式設計例項

Linux系統下的多執行緒遵循POSIX執行緒介面,稱為 pthread。編寫Linux下的多執行緒程式,需要使用標頭檔案pthread.h,連線時需要使用庫libpthread.a。順便說一下,Linux 下pthread的實現是通過系統呼叫clone()來實現的。clone()是 Linux所特有的系統呼叫,它的使用方式類似fork,關於clone()的詳細情況,有興趣的讀者可以去檢視有關文件說明。下面我們展示一個最簡單的多執行緒程式 pthread_create.c。


一個重要的執行緒建立函式原型:
#include <pthread.h>
int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr, void *(*start_rtn)(void),void *restrict arg);

    返回值:若是成功建立執行緒返回0,否則返回錯誤的編號
    形式引數:
                pthread_t *restrict tidp 要建立的執行緒的執行緒id指標
                const pthread_attr_t *restrict attr 建立執行緒時的執行緒屬性
                void* (start_rtn)(void) 返回值是void型別的指標函式
                void *restrict arg   start_rtn的行參
               
例程1:                              
    功能:建立一個簡單的執行緒
    程式名稱: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 <stdio.h>
#include <pthread.h>

void *myThread1(void)
{
    int i;
    for (i=0; i<100; i++)
    {
        printf("This is the 1st pthread,created by zieckey./n");
        sleep(1);//Let this thread to sleep 1 second,and then continue to run
    }
}

void *myThread2(void)
{
    int i;
    for (i=0; i<100; i++)
    {
        printf("This is the 2st pthread,created by zieckey./n");
        sleep(1);
    }
}

int main()
{
    int i=0, ret=0;
    pthread_t id1,id2;
  
    ret = pthread_create(&id2, NULL, (void*)myThread1, NULL);
    if (ret)
    {
        printf("Create pthread error!/n");
        return 1;
    }
  
    ret = pthread_create(&id2, NULL, (void*)myThread2, NULL);
    if (ret)
    {
        printf("Create pthread error!/n");
        return 1;
    }
  
    pthread_join(id1, NULL);
    pthread_join(id2, NULL);
  
    return 0;
}


  我們編譯此程式:
# gcc pthread_create.c -lpthread

因為pthread的庫不是linux系統的庫,所以在進行編譯的時候要加上-lpthread,否則編譯不過,會出現下面錯誤
thread_test.c: 在函式 ‘create’ 中:
thread_test.c:7: 警告: 在有返回值的函式中,程式流程到達函式尾
/tmp/ccOBJmuD.o: In function `main':thread_test.c:(.text+0x4f):對‘pthread_create’未定義的引用
collect2: ld 返回 1

  執行,我們得到如下結果:
# ./a.out
This is the 1st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 1st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 2st pthread,created by zieckey.
This is the 1st pthread,created by zieckey.
....

兩個執行緒交替執行。
此例子介紹了建立執行緒的方法。
下面例子介紹向執行緒傳遞引數。


例程2:
    功能:向新的執行緒傳遞整形值
    程式名稱:pthread_int.c
/********************************************************************************************
**    Name:pthread_int.c
**    Used to study the multithread programming in Linux OS
**    Pass a parameter to the thread.
**    Author:zeickey
**    Date:2006/9/16      
**    Copyright (c) 2006,All Rights Reserved!
*********************************************************************************************/

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

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


    執行結果:

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


    例程總結:
    可以看出來,我們在main函式中傳遞的整行指標,傳遞到我們新建的執行緒函式中。
    在上面的例子可以看出來我們向新的執行緒傳入了另一個執行緒的int資料,執行緒之間還可以傳遞字串或是更復雜的資料結構。

例程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 <pthread.h>
#include <stdio.h>
#include <unistd.h>

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


    執行結果:
The parameter passed from main function is zieckey
pthread is created...


    例程總結:
    可以看出來main函式中的字串傳入了新建的執行緒中。

例程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 <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

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


    執行結果:
menber->a = 4
menber->s = zieckey
pthread is created...

    例程總結:
    可以看出來main函式中的一個結構體傳入了新建的執行緒中。
    執行緒包含了標識程序內執行環境必須的資訊。他集成了程序中的所有資訊都是對執行緒進行共享的,包括文字程式、程式的全域性記憶體和堆記憶體、棧以及檔案描述符。
  

例程5:
    程式目的:驗證新建立的執行緒可以共享程序中的資料
    程式名稱: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 <stdio.h>
#include <pthread.h>
#include <unistd.h>

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


    執行結果:
new pthread ...
a=5
new thread is created ...


    例程總結:
可以看出來,我們在主執行緒更改了我們的全域性變數a的值的時候,我們新建立的執行緒則打印出來了改變的值,可以看出可以訪問執行緒所在程序中的資料資訊。

         2、執行緒的終止

    如果程序中任何一個執行緒中呼叫exit,_Exit,或者是_exit,那麼整個程序就會終止,
    與此類似,如果訊號的預設的動作是終止程序,那麼,把該訊號傳送到執行緒會終止程序。
    執行緒的正常退出的方式:
       (1) 執行緒只是從啟動例程中返回,返回值是執行緒中的退出碼
       (2) 執行緒可以被另一個程序進行終止
       (3) 執行緒自己呼叫pthread_exit函式
    兩個重要的函式原型:

#include <pthread.h>
void pthread_exit(void *rval_ptr);
/*rval_ptr 執行緒退出返回的指標*/

int pthread_join(pthread_t thread,void **rval_ptr);
   /*成功結束程序為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 <stdio.h>
#include <pthread.h>
#include <unistd.h>

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


    執行結果:
new thread is created ...
thread is exit code 8

    例程總結:
可以看出來,執行緒退出可以返回執行緒的int數值。執行緒退出不僅僅可以返回執行緒的int數值,還可以返回一個複雜的資料結構。

    例程7
    程式目的:執行緒結束返回一個複雜的資料結構
    程式名稱:pthread_return_struct.c
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

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


    執行結果:

main ...
new thread ...
c->a = 8
c->b = zieckey


例程總結:
一定要記得返回的資料結構要是在這個資料要返回的結構沒有釋放的時候應用,
如果資料結構已經發生變化,那返回的就不會是我們所需要的,而是髒資料
3、執行緒標識

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

pid_t getpid(void);
    getpid()用來取得目前程序的程序識別碼,函式說明

    例程8
    程式目的:實現在新建立的執行緒中列印該執行緒的id和程序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 <stdio.h>
#include <pthread.h>
#include <unistd.h> /*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

    執行結果:

Main thread is starting ...
The main process's pid is 3307
New thread ....
This thread's id is 3086347152
The process pid is 3307

相關推薦

Linux執行(pthread)程式設計例項

Linux系統下的多執行緒遵循POSIX執行緒介面,稱為 pthread。編寫Linux下的多執行緒程式,需要使用標頭檔案pthread.h,連線時需要使用庫libpthread.a。順便說一下,Linux 下pthread的實現是通過系統呼叫clone()來實現的。clon

linux 執行epoll程式設計 -socket

轉載自:http://blog.csdn.net/susubuhui/article/details/37906287 Linux socket+epoll+pthread+佇列 實現併發伺服器。程式碼有封裝,僅做參考 Linux下多執行緒epoll程式設計,在高併發下測

linux執行程式設計pthread 同步 互斥

前言 linux下關於並行程式設計有兩種實現方式:fork和pthread_create;其實核心中的執行路徑是相同的,只是flags不一樣罷了。本文的主題是關於pthread_create多執行緒

C/C++ Linux執行程式設計 #include

1.最基礎,程序同時建立5個執行緒,各自呼叫同一個函式 #include <iostream> #include <pthread.h> //多執行緒相關操作標頭檔案,可移植眾多平臺   using namespa

Linux執行程式設計遇到的一些問題

今天在學習了Linux的多執行緒程式設計的基礎的知識點。於是就試著做了一個簡單的Demo。本以為會得到預期的結果。不成想卻遇到了意想不到的問題。 程式碼展示 我的C 程式碼很簡單,就是一個簡單的示例程式,如下: #include <s

Linux執行程式設計學習【2】——同代…

要想一份程式碼在linux下能編譯,在windows下也能編譯,就得應用巨集處理。最初產生這個構想,是在學習opengl的時候,發覺glut庫是跨平臺的,檢視原始碼後發覺glut裡面進行了很多巨集處理。這是第一次知道編譯器在進行編譯的時候也會定義一些巨集關鍵字。 程式結果如下: 在win8系統下,用d

Linux執行程式設計互斥鎖和條件變數的簡單使用

Linux下的多執行緒遵循POSIX執行緒介面,稱為pthread。編寫Linux下的多執行緒程式,需要使用標頭檔案pthread.h,連結時需要使用庫libpthread.a。執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位。執行緒

linux 執行1

舉例UNIX International 執行緒 UNIX International 執行緒的標頭檔案是<thread.h> [1]  ,僅適用於Sun Solaris作業系統。所以UNIX International執行緒也常被俗稱為Solaris執

為什麼linux執行程式如此消耗虛擬記憶體

最近遊戲已上線運營,進行伺服器記憶體優化,發現一個非常奇妙的問題,我們的認證伺服器(AuthServer)負責跟第三方渠道SDK打交道(登陸和充值),由於採用了curl阻塞的方式,所以這裡開了128個執行緒,奇怪的是每次剛啟動的時候佔用的虛擬記憶體在2.3G,然後每次處理訊息就增加64M,

Linux執行模擬生產者/消費者問題

/*用執行緒的同步和互斥來實現"生產者-消費者"問題.*/ /* 多生產者多消費者多緩衝區 生產者和消費者不可同時進行 */ #include <stdio.h> #include <stdlib.h> //#include <unistd.h

windows和linux執行的一些區別

我認為linux的多執行緒不如windows。理由如下:一、功能WaitForSingleObject在linux下可以用pthread_cond_wait來替代實現,但是pthread_cond_wait不能用來等待thread handle。要等待thread handl

Linux執行檔案傳輸

要求:服務端客戶端分辨各佔一個程序,客戶端中可設定TCP連線數n,之後將檔案等分成n塊同時傳輸。 思路: 在網上查到了許多關於Linux下socket檔案傳輸的文章,受益許多,其中有個部落格寫的很好 連結:http://blog.csdn.net/zhqia

linux執行中條件變數的用法

使用條件變數最大的好處是可以避免忙等。相當與多執行緒中的訊號。 條件變數是執行緒中的東西就是等待某一條件的發生和訊號一樣以下是說明,條件變數使我們可以睡眠等待某種條件出現。條件變數是利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:一個執行緒等待"條件變數的條件成立"而掛起;另一個執行緒

linux執行同步機制之訊號量、互斥量、讀寫鎖、條件變數

之前有寫過類似的部落格,這東西不用老忘,現在又有更清晰的理解了。 一、訊號量 編譯時候加入-lrt 訊號量最基本的兩個操作就是PV操作:P()操作實現訊號量減少,V()操作實現訊號量的增加 訊號量的值取決於訊號量的型別,訊號量的型別有多種: (1)二進位制訊號量:0與1.

Linux執行,斷點續傳,命令列下載工具axel

 參考:http://www.2cto.com/os/201202/118482.html 1、安裝方法Ubuntu sudo apt-get install axel  2、man一下 名稱        Axel - Linux 下輕量的下載加速器。 總覽      

c++ 網路程式設計(九)TCP/IP LINUX/windows 執行超詳細教程 以及 執行實現服務端

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <process.h> #include <winsock2.h> #include <win

c++ 網路程式設計(九)TCP/IP LINUX/windows 執行超詳細教程 以及 執行實現服務端

原文作者:aircraft 原文連結:https://www.cnblogs.com/DOMLX/p/9661012.html  先講Linux下(windows下在後面可以直接跳到後面看): 一.執行緒基本概念 前面我們講過多程序伺服器,但我們知道它開銷很大

Linux c執行程式設計的4個例項

在主流的作業系統中,多工一般都提供了程序和執行緒兩種實現方式,程序享有獨立的程序空間,而執行緒相對於程序來說是一種更加輕量級的多工並行,多執行緒之間一般都是共享所在程序的記憶體空間的。   Linux也不例外,雖然從核心的角度來看,執行緒體現為一種對程序的"克隆"(clon

linux tcp執行伺服器與客戶端程式設計例項

伺服器端: #include<iostream> #include<arpa/inet.h> #include<sys/socket.h> #include<cstdlib> #include<cstdio> #i

Linux執行程式設計-pthread

我們編譯此程式: gcc example1.c -lpthread -o example1 執行example1,我們得到如下結果: This is the main process. This is a pthread. This is the main process. This is the main