linux應用編程:thread總結

來源:互聯網
上載者:User
1:線程與進程的區別

2:線程同步:互斥鎖
3:線程同步:條件變數
4:線程同步:post訊號量在代碼中有執行個體。5:線程退出
6:線程範例程式碼
/* ============================================================================ Name        : threadDemo.c Author      :  Version     : Copyright   : Your copyright notice Description : Hello World in C, Ansi-style ============================================================================ */#include <syslog.h>#include <pthread.h>#include <sys/types.h>#include <sys/msg.h>#include <sys/stat.h>#include <stddef.h>                     /* For definition of offsetof() */#include <stdarg.h>                     /* For definition of offsetof() */#include <limits.h>#include <fcntl.h>#include <signal.h>#include <sys/wait.h>#include <sys/types.h>  /* Type definitions used by many programs */#include <stdio.h>      /* Standard I/O functions */#include <stdlib.h>     /* Prototypes of commonly used library functions,                           plus EXIT_SUCCESS and EXIT_FAILURE constants */#include <unistd.h>     /* Prototypes for many system calls */#include <errno.h>      /* Declares errno and defines error constants */#include <string.h>     /* Commonly used string-handling functions */#include <sys/param.h>#include <pthread.h>#include <semaphore.h>typedef enum { FALSE, TRUE } Boolean;/*使用多線程的理由之一是和進程相比,它是一種非常"節儉"的多任務操作方式。我們知道,在Linux 系統下,啟動一個新的進程必須分配給它獨立的地址空間,建立眾多的資料表來維護它的程式碼片段、堆棧段和資料區段,這是一種"昂貴"的多任務工作方式。而運行於一個進程中的多個線程,它們彼此之間使用相同的地址空間,共用大部分資料,啟動一個線程所花費的空間遠遠小於啟動一個進程所花費的空間,而且,線程間彼此切換所需的時間也遠遠小於進程間切換所需要的時間。據統計,總的說來,一個進程的開銷大約是一個線程開銷的30 倍左右,當然,在具體的系統上,這個資料可能會有較大的區別 */struct menber{int a;char *s;};void cleanup(void *arg){printf("cleanup arg:%s\n",arg);}void *thread_one(void *arg){pid_t pid;pthread_t tid;pid=getpid();tid=pthread_self();struct menber *parameter=(struct menber *)arg;pthread_cleanup_push(cleanup,(void*)parameter->s); //atexit();printf("thread_one: the pid is %u ,the thread is %u \n",pid,tid);printf("a:%d s:%s\n",parameter->a,parameter->s);pthread_cleanup_pop(1); //pthread_cleanup_pop(0);//atexit();pthread_exit((void *)parameter->a);}void *thread_two(void *arg){pid_t pid;pthread_t tid;pid=getpid();tid=pthread_self();printf("thread_two: the pid is %u ,the thread is %u \n",pid,tid);return (void*)8;}void pthreadParamter(){int err,stat_val;;pid_t pid,childPid;pthread_t tid_one,tid_two;pid=getpid();tid_one=pthread_self();void *retValue_one,*retValue_two;struct menber parameter;parameter.a=123456;parameter.s="suiyuan";if((childPid=fork())==-1){perror("fork");exit(EXIT_FAILURE);}else if(childPid==0){err=pthread_create(&tid_one,NULL,thread_one,(void *)¶meter);if(err!=0){printf("error message is:%s\n",strerror(err));exit(1);}pthread_join(tid_one,&retValue_one);printf("pthread_join,thread_one return value:%d\n",(int)retValue_one);}else{pthread_create(&tid_two,NULL,(void *)thread_two,NULL);if(err!=0){printf("error message is:%s\n",strerror(err));exit(1);}pthread_join(tid_two,&retValue_two);printf("pthread_join,thread_two return value:%d\n",(int)retValue_two);printf("pid:%d getpid:%d\n",pid,getpid());waitpid(childPid, &stat_val, 0);if (WIFEXITED(stat_val)){printf("Child exited with code %d\n", WEXITSTATUS(stat_val));}else if (WIFSIGNALED(stat_val)){printf("Child terminated abnormally, signal %d\n", WTERMSIG(stat_val));}}printf("main thread:the pid is %u ,the thread is %u \n",pid,tid_one);}/* 如果進程中任何一個線程中調用exit,_Exit,或者是_exit,那麼整個進程就會終止,與此類似,如果訊號的預設的動作是終止進程,那麼,把該訊號發送到線程會終止進程。線程的正常退出的方式:(1) 線程只是從啟動常式中返回,傳回值是線程中的退出碼(2) 線程可以被另一個進程進行終止(3) 線程自己調用pthread_exit 函數 *///************************************************************************************************#if 1static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;#endif#if 1static int avail = 0;static void *pthread_mutex_lock_Func(void *arg){    int cnt = *((int *) arg);    int s, j;    printf("pthread_mutex_lock_Func:arg:%d\n",cnt);    sleep(1);    for (j = 0; j < cnt; j++) {        sleep(2);        /* Code to produce a unit omitted */        s = pthread_mutex_lock(&mtx);        if (s != 0)            perror("pthread_mutex_lock");        avail++;        /* Let consumer know another unit is available */        s = pthread_mutex_unlock(&mtx);        if (s != 0)            perror("pthread_mutex_unlock");#if 1        s = pthread_cond_signal(&cond);         /* Wake sleeping consumer */        if (s != 0)            perror("pthread_cond_signal");#endif    }    return NULL;}void pthread_mutex_lock_test(int num){    pthread_t tid;    int s;    int totRequired;            /* Total number of units that all threads will produce */    int numConsumed;            /* Total units so far consumed */    Boolean done;    time_t t;    t = time(NULL);    /* Create all threads */    {        totRequired = num;        printf("totRequired:%d\n",totRequired);        s = pthread_create(&tid, NULL, pthread_mutex_lock_Func, (void *)&totRequired);        if (s != 0)        perror("pthread_create");    }    /* Use a polling loop to check for available units */    numConsumed = 0;    done = FALSE;    for (;;) {        s = pthread_mutex_lock(&mtx);        if (s != 0)        {            perror("pthread_mutex_lock");        }    //    while (avail == 0)        {            /* Wait for something to consume */            s = pthread_cond_wait(&cond, &mtx);            if (s != 0)            perror("pthread_cond_wait");        } //       while (avail > 0)        {             /* Consume all available units */            /* Do something with produced unit */        numConsumed ++;        printf("condition is ture;T=%ld: avail=%d numConsumed=%d\n", (long) (time(NULL) - t),avail,numConsumed);            avail--;            done = numConsumed >= totRequired;        }        s = pthread_mutex_unlock(&mtx);        if (s != 0)        {        perror("pthread_mutex_unlock");        }        if (done)        {            break;        }        /* Perhaps do other work here that does not require mutex lock */    }    exit(EXIT_SUCCESS);}#endif//***************************************condition example***********************************************#if 1/*static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;*/static int glob = 0;static void cleanupHandler(void *arg)    /* Free memory pointed to by 'arg' and unlock mutex */{    int s;    printf("cleanup: freeing block at %p\n", arg);    free(arg);    printf("cleanup: unlocking mutex\n");    s = pthread_mutex_unlock(&mtx);    if (s != 0)    perror("pthread_mutex_unlock");}static void *mutex_conditionFunc(void *arg){    int s;    void *buf = NULL;                   /* Buffer allocated by thread */    buf = malloc(0x10000);              /* Not a cancellation point */    printf("thread:  allocated memory at %p\n", buf);    s = pthread_mutex_lock(&mtx);       /* Not a cancellation point */    if (s != 0)    {    perror("pthread_mutex_lock");    }    pthread_cleanup_push(cleanupHandler, buf);  //  while (glob == 0)    {    printf("pthread_cond_wait become to ture\n");        s = pthread_cond_wait(&cond, &mtx);     /* A cancellation point */        if (s != 0)        {        perror("pthread_cond_wait");        }    }    printf("thread:  condition wait loop completed\n");    pthread_cleanup_pop(1);             /* Executes cleanup handler */    return NULL;}void mutex_condition_test(int argc){    pthread_t thr;    void *res;    int s;    s = pthread_create(&thr, NULL, mutex_conditionFunc, NULL);    if (s != 0)    {    perror("pthread_create");    }    printf("main: sleep 5s\n");    sleep(5);                   /* Give thread a chance to get started */    if (argc == 1)    {            /* Cancel thread */        printf("main:    about to cancel thread\n");        s = pthread_cancel(thr);        if (s != 0)        {        perror("pthread_cancel");        }    } else    {                    /* Signal condition variable */        printf("main:    about to signal condition variable\n");        glob = 1;        s = pthread_cond_signal(&cond);        if (s != 0)        {        perror("pthread_cond_signal");        }    }    s = pthread_join(thr, &res);    if (s != 0)    perror("pthread_join");    if (res == PTHREAD_CANCELED)        printf("main:    thread was canceled\n");    else        printf("main:    thread terminated normally\n");    exit(EXIT_SUCCESS);}#endifstatic int globCount = 0;static sem_t postsem;static void * threadPostSemaphoresFunc(void *arg)                  /* Loop 'arg' times incrementing 'glob' */{    int loops = *((int *) arg);    int loc, j;    for (j = 0; j < loops; j++) {        if (sem_wait(&postsem) == -1)            perror("sem_wait");        loc = globCount;        loc++;        globCount = loc;        printf("threadPostSemaphoresFunc:loops %d globCount %d\n",loops, globCount);        sleep(1);        if (sem_post(&postsem) == -1)            perror("sem_post");    }    return NULL;}void threadAndPostSemaphoresTest(int loops){    pthread_t t1, t2;    int s,loops1=loops+1;    /* Initialize a semaphore with the value 1 */    if (sem_init(&postsem, 0, 1) == -1)        perror("sem_init");    /* Create two threads that increment 'glob' */    s = pthread_create(&t1, NULL, threadPostSemaphoresFunc, &loops1);    if (s != 0)    perror("pthread_create");    s = pthread_create(&t2, NULL, threadPostSemaphoresFunc, &loops);    if (s != 0)    perror("pthread_create");    /* Wait for threads to terminate */    s = pthread_join(t1, NULL);    if (s != 0)    perror("pthread_join");    s = pthread_join(t2, NULL);    if (s != 0)    perror("pthread_join");    printf("globCount = %d\n", globCount);    exit(EXIT_SUCCESS);}usageError(const char *progName, const char *msg){    if (msg != NULL)    {        fprintf(stderr, "%s", msg);    }    fprintf(stderr, "Usage: %s [options] parameter\n", progName);    fprintf(stderr, "Usage: %s [tm:c:p:] parameter\n", progName);    fprintf(stderr, "Usage: %s  -t ;to execute:pthreadParamter()\n", progName);    fprintf(stderr, "Usage: %s  -m parameter;to execute:pthread_mutex_lock_test()\n", progName);    fprintf(stderr, "Usage: %s  -c [parameter];to execute:mutex_condition_test()\n", progName);    fprintf(stderr, "Usage: %s  -p parameter;to execute:threadAndPostSemaphoresTest()\n", progName);    fprintf(stderr, "Usage: %s  -h ;to execute:help\n", progName);    exit(EXIT_FAILURE);}int main(int argc, char *argv[]){int opt;if(argc==1){perror("");usageError(argv[0], NULL);}while ((opt = getopt(argc, argv, "tm:c:k:p:")) != -1) {switch (opt) {case 't':pthreadParamter();break;case 'm':if(optarg!=NULL){printf("optopt:%c   :%d\n",optopt,atoi(optarg));pthread_mutex_lock_test(atoi(optarg));}else{usageError(argv[0], NULL);}break;case 'c':if(optarg!=NULL){printf("optopt:%c   :%d\n",optopt,atoi(optarg));mutex_condition_test(atoi(optarg));}else{usageError(argv[0], NULL);}break;case 'p':if(optarg!=NULL){printf("optopt:%c   :%d\n",optopt,atoi(optarg));threadAndPostSemaphoresTest(atoi(optarg));}else{usageError(argv[0], NULL);}break;default:usageError(argv[0], NULL);}}return EXIT_SUCCESS;}
7:代碼執行結果




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.