zoukankan      html  css  js  c++  java
  • [转载]Linux多线程Pthread

    简介

    POSIX thread 简称为pthread,Posix线程是一个POSIX标准线程.该标准定义内部API创建和操纵线程.

    作用

    线程库实行了POSIX线程标准通常称为pthreads.pthreads是最常用的POSIX系统如Linux和Unix,而微软Windowsimplementations同时存在.举例来说,pthreads-w32可支持MIDP的pthread   

    Pthreads定义了一套 C程序语言类型、函数与常量,它以 pthread.h 头文件和一个线程库实现。

    数据类型

    pthread_t:线程句柄   

    pthread_attr_t:线程属性

    线程操纵函数(简介起见,省略参数)

    pthread_create():创建一个线程   

    pthread_exit():终止当前线程   

    pthread_cancel():中断另外一个线程的运行   

    pthread_join():阻塞当前的线程,直到另外一个线程运行结束   

    pthread_attr_init():初始化线程的属性   

    pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)

    pthread_attr_getdetachstate():获取脱离状态的属性   

    pthread_attr_destroy():删除线程的属性   

    pthread_kill():向线程发送一个信号

    同步函数

    用于 mutex 和条件变量   

    pthread_mutex_init() 初始化互斥锁   

    pthread_mutex_destroy() 删除互斥锁   

    pthread_mutex_lock():占有互斥锁(阻塞操作)   

    pthread_mutex_trylock():试图占有互斥锁(不阻塞操作)。当互斥锁空闲时将占有该锁;否则立即返回  

    pthread_mutex_unlock(): 释放互斥锁   

    pthread_cond_init():初始化条件变量   

    pthread_cond_destroy():销毁条件变量   

    pthread_cond_wait(): 等待条件变量的特殊条件发生

    pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程      

    Thread-local storage(或者以Pthreads术语,称作 线程特有数据):   

    pthread_key_create(): 分配用于标识进程中线程特定数据的键   

    pthread_setspecific(): 为指定线程特定数据键设置线程特定绑定   

    pthread_getspecific(): 获取调用线程的键绑定,并将该绑定存储在 value 指向的位置中   

    pthread_key_delete(): 销毁现有线程特定数据键

    与一起工作的工具函数

    pthread_equal(): 对两个线程的线程标识号进行比较   

    pthread_detach(): 分离线程   

    pthread_self(): 查询线程自身线程标识号

    详细请参见:

    Linux多线程pthread:     http://blog.csdn.net/Sunboy_2050/archive/2010/10/04/5920936.aspx 

    Pthread多线程学习小结: http://blog.csdn.net/Sunboy_2050/archive/2010/10/04/5921003.aspx

    ===================================================================

    多线程创建

    参考代码:

    1. #include<stdio.h>   
    2. #include<pthread.h>   
    3. #include<string.h>   
    4. #include<sys/types.h>   
    5. #include<unistd.h>   
    6. pthread_t main_tid;  
    7. void print_ids(const char *str)  
    8. {  
    9.     pid_t pid;      //进程id   
    10.     pthread_t tid;  //线程id   
    11.     pid = getpid();       //获取当前进程id   
    12.     tid = pthread_self(); //获取当前线程id   
    13.     printf("%s pid: %u tid: %u (0x%x)/n",  
    14.                 str,  
    15.                 (unsigned int)pid,  
    16.                 (unsigned int)tid,  
    17.                 (unsigned int)tid);  
    18. }  
    19. void *func(void *arg)  
    20. {  
    21.     print_ids("new  thread:");  
    22.     return ((void *)0);  
    23. }  
    24. int main()  
    25. {  
    26.     int err;  
    27.     err = pthread_create(&main_tid, NULL, func, NULL); //创建线程   
    28.     if(err != 0){  
    29.         printf("create thread error: %s/n",strerror(err));  
    30.         return 1;  
    31.     }  
    32.     printf("main thread: pid: %u tid: %u (0x%x)/n",   
    33.                 (unsigned int)getpid(),  
    34.                 (unsigned int)pthread_self(),  
    35.                 (unsigned int)pthread_self());  
    36.     print_ids("main thread:");  
    37.     sleep(1);  
    38.     return 0;  
    39. }  
     

    运行结果:

    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ gcc -Wall -o pthread_create pthread_create.c -lpthread   

    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ ./pthread_create 

    main thread: pid: 12531 tid: 2505487232 (0x9556b380)

    main thread: pid: 12531 tid: 2505487232 (0x9556b380)

    new  thread: pid: 12531 tid: 1084229984 (0x40a00960)

    ===================================================================

    多线程条件变量

    参考代码:

    1. #include <stdio.h>   
    2. #include <pthread.h>   
    3. #include <unistd.h>   
    4.   
    5. pthread_mutex_t counter_lock;   //互斥锁   
    6. pthread_cond_t counter_nonzero; //条件变量   
    7. int counter = 0;  
    8. int estatus = -1;  
    9.   
    10. void *decrement_counter(void *argv);  
    11. void *increment_counter(void *argv);  
    12.   
    13. //******* 主函数 *******//   
    14. int main(int argc, char **argv)  
    15. {  
    16.     printf("counter: %d/n", counter);  
    17.     pthread_t thd1, thd2;  
    18.     int ret;  
    19.   
    20.     //初始化   
    21.     pthread_mutex_init(&counter_lock, NULL);  
    22.     pthread_cond_init(&counter_nonzero, NULL);  
    23.       
    24.     ret = pthread_create(&thd1, NULL, decrement_counter, NULL); //创建线程1   
    25.     if(ret){  
    26.         perror("del:/n");  
    27.         return 1;  
    28.     }  
    29.   
    30.     ret = pthread_create(&thd2, NULL, increment_counter, NULL); //创建线程2   
    31.     if(ret){  
    32.         perror("inc: /n");  
    33.         return 1;  
    34.     }  
    35.   
    36.     int counter = 0;  
    37.     while(counter != 10){  
    38.         printf("counter(main): %d/n", counter); //主线程   
    39.         sleep(1);  
    40.         counter++;  
    41.     }  
    42.   
    43.     pthread_exit(0);  
    44.       
    45.     return 0;  
    46. }  
    47.   
    48. void *decrement_counter(void *argv)  
    49. {  
    50.     printf("counter(decrement): %d/n", counter);  
    51.     pthread_mutex_lock(&counter_lock);  
    52.     while(counter == 0)  
    53.         pthread_cond_wait(&counter_nonzero, &counter_lock); //进入阻塞(wait),等待激活(signal)   
    54.       
    55.     printf("counter--(before): %d/n", counter);      
    56.     counter--; //等待signal激活后再执行   
    57.     printf("counter--(after): %d/n", counter);      
    58.     pthread_mutex_unlock(&counter_lock);   
    59.   
    60.     return &estatus;  
    61. }  
    62.   
    63. void *increment_counter(void *argv)  
    64. {  
    65.     printf("counter(increment): %d/n", counter);  
    66.     pthread_mutex_lock(&counter_lock);  
    67.     if(counter == 0)  
    68.         pthread_cond_signal(&counter_nonzero); //激活(signal)阻塞(wait)的线程(先执行完signal线程,然后再执行wait线程)   
    69.   
    70.     printf("counter++(before): %d/n", counter);      
    71.     counter++;   
    72.     printf("counter++(after): %d/n", counter);      
    73.     pthread_mutex_unlock(&counter_lock);  
    74.   
    75.     return &estatus;  
    76. }  

    运行结果:

    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ gcc -Wall -o pthread_cond2 pthread_cond2.c -lpthread

    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ ./pthread_cond2 

    counter: 0

    counter(main): 0

    counter(decrement): 0

    counter(increment): 0

    counter++(before): 0

    counter++(after): 1

    counter--(before): 1

    counter--(after): 0

    counter(main): 1

    counter(main): 2

    counter(main): 3

    counter(main): 4

    counter(main): 5

    counter(main): 6

    counter(main): 7

    counter(main): 8

    counter(main): 9

    详细解释,请见:http://blog.csdn.net/Sunboy_2050/archive/2010/11/24/6031723.aspx

    ===================================================================

    多线程的创建特殊数据键

    参考代码:

    1. #include <stdio.h>   
    2. #include <pthread.h>   
    3. #include <unistd.h>   
    4.   
    5. pthread_key_t key; //声明参数key   
    6.   
    7. void echomsg(void *arg) //析构处理函数   
    8. {  
    9.     printf("destruct executed in thread = %u, arg = %p/n",   
    10.                 (unsigned int)pthread_self(),  
    11.                 arg);     
    12. }  
    13.   
    14. void *child_1(void *arg)  
    15. {  
    16.     pthread_t tid;  
    17.      
    18.     tid = pthread_self();  
    19.     printf("%s: thread %u enter/n", (char *)arg, (unsigned int)tid);  
    20.       
    21.     pthread_setspecific(key, (void *)tid);  // 与key值绑定的value(tid)   
    22.     printf("%s: thread %u returns %p/n",    // %p 表示输出指针格式    
    23.                 (char *)arg,  
    24.                 (unsigned int)tid,   
    25.                 pthread_getspecific(key));  // 获取key值的value   
    26.     sleep(1);  
    27.     return NULL;  
    28. }  
    29.   
    30. void *child_2(void *arg)  
    31. {  
    32.     pthread_t tid;  
    33.      
    34.     tid = pthread_self();  
    35.     printf("%s: thread %u enter/n", (char *)arg, (unsigned int)tid);  
    36.       
    37.     pthread_setspecific(key, (void *)tid);  
    38.     printf("%s: thread %u returns %p/n",   
    39.                 (char *)arg,  
    40.                 (unsigned int)tid,   
    41.                 pthread_getspecific(key));  
    42.     sleep(1);  
    43.     return NULL;  
    44. }  
    45.   
    46. //******* 主函数 *******//   
    47. int main(void)  
    48. {  
    49.     pthread_t tid1, tid2;  
    50.       
    51.     printf("hello main/n");  
    52.       
    53.     pthread_key_create(&key, echomsg); //创建key   
    54.       
    55.     pthread_create(&tid1, NULL, child_1, (void *)"child_1"); //创建带参数的线程,需要强制转换   
    56.     pthread_create(&tid2, NULL, child_2, (void *)"child_2");  
    57.   
    58.     sleep(3);  
    59.     pthread_key_delete(key); //清除key   
    60.     printf("bye main/n");  
    61.       
    62.     pthread_exit(0);  
    63.     return 0;  
    64. }  

    运行结果:

    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ gcc -Wall -o pthread_setspecific pthread_setspecific.c -lpthread
    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ ./pthread_setspecific                                          
    hello main
    child_1: thread 1084229984 enter
    child_1: thread 1084229984 returns 0x40a00960
    child_2: thread 1094719840 enter
    child_2: thread 1094719840 returns 0x41401960
    destruct executed in thread = 1084229984, arg = 0x40a00960
    destruct executed in thread = 1094719840, arg = 0x41401960
    bye main

    附加参考——函数原型:

    Posix定义了两个API分别用来创建和注销TSD:

    int pthread_key_create(pthread_key_t *key, void (*destr_function) (void *))
    注销一个TSD采用如下API:
    int pthread_key_delete(pthread_key_t key)
    int pthread_setspecific(pthread_key_t key, const void *pointer)
    void * pthread_getspecific(pthread_key_t key)
    参考网址:

    ===================================================================

    多线程的创建特殊数据键

    参考代码:

    1. #include <stdio.h>   
    2. #include <pthread.h>   
    3. #include <unistd.h>   
    4.   
    5. pthread_once_t once = PTHREAD_ONCE_INIT; //声明变量   
    6.   
    7. //once_run()函数仅执行一次,且究竟在哪个线程中执行是不定的   
    8. //尽管pthread_once(&once,once_run)出现在两个线程中   
    9. //函数原型:int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))   
    10. void once_run(void)  
    11. {  
    12.     printf("Func: %s in thread: %u/n",   
    13.                 __func__,   
    14.                 (unsigned int)pthread_self());  
    15. }  
    16.   
    17. void *child_1(void *arg)  
    18. {  
    19.     pthread_t tid;  
    20.   
    21.     tid = pthread_self();  
    22.     pthread_once(&once, once_run); //调用once_run   
    23.     printf("%s: thread %d returns/n", (char *)arg, (unsigned int)tid);  
    24.   
    25.     return NULL;  
    26. }  
    27.   
    28. void *child_2(void *arg)  
    29. {  
    30.     pthread_t tid;  
    31.   
    32.     tid = pthread_self();  
    33.     pthread_once(&once, once_run); //调用once_run   
    34.     printf("%s: thread %d returns/n", (char *)arg, (unsigned int)tid);  
    35.   
    36.     return NULL;  
    37. }  
    38.   
    39. //******* main *******//   
    40. int main(void)  
    41. {  
    42.     pthread_t tid1, tid2;  
    43.   
    44.     printf("hello main/n");  
    45.     pthread_create(&tid1, NULL, child_1, (void *)"child_1");  
    46.     pthread_create(&tid2, NULL, child_2, (void *)"child_2");  
    47.   
    48.     pthread_join(tid1, NULL);  //main主线程等待线程tid1返回   
    49.     pthread_join(tid2, NULL);  //main主线程等待线程tid2返回   
    50.     printf("bye main/n");  
    51.   
    52.     return 0;  
    53. }  

    运行结果:

    work@db-testing-com06-vm3.db01.baidu.com pthread]$ gcc -Wall -o pthread_once pthread_once.c -lpthread
    [work@db-testing-com06-vm3.db01.baidu.com pthread]$ ./pthread_once                                   
    hello main
    Func: once_run in thread: 1084229984
    child_1: thread 1084229984 returns
    child_2: thread 1094719840 returns
    bye main

  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/fx2008/p/2181090.html
Copyright © 2011-2022 走看看