底层多线程pthread

POSIX thread 简称为pthread,Posix线程是一个POSIX标准线程。该标准定义内部API创建和操纵线程。 Pthreads定义了一套 C程序语言类型、函数与常量,它以 pthread.h 头文件和一个线程库实现。

在进行os x和ios开发的时候,经常会用到多线程来提高性能。我们经常用操作对象(operation objects)和GCD来实现并发,但是os x和ios还提供了另外的接口来实现多线程,那就是POSIX threads API。

POSIX是一个标准,是开发跨平台多线程的最佳方法。它是基于c语言的,很高效也很方便。


POSIX标准包括3方面的内容,1,线程管理。2,互斥量(mutex)。3,条件变量(condition variables)

POSIX函数的命名规则:

pthread_    线程本身和各种线程相关函数

pthread_attr_线程属性对象

phtread_mutex_ 互斥量函数

pthread_mutexattr_互斥量属性对象

pthread_cond_   条件变量

pthread_condattr_ 条件变量属性对象

pthread_key_ 线程数据键

线程管理又包括:创建、分离、连接等内容。

创建和结束线程函数pthread_create()创建一个线程

pthread_exit()结束一个线程

pthread_attr_init()初始化一个线程属性

pthread_attr_destroy()消除一个线程属性


线程标识:

每个线程有一个线程ID。进程ID在整个系统中是唯一的,单线程ID不同,线程ID只在它所属的进程环境中有效。线程IDpthread_t数据类型来表示,它可能是一个结构,因此,必须使用pthread_equal函数来对两个线程ID进行比较。线程可以调用pthread_self函数获得自身的线程ID

  1. #include <pthread.h>  
  2. int pthread_equal(pthread_t tid1, pthread_t tid2);  
  3. pthread_t pthread_self(void);  

创建线程:
  1. #include <pthread.h>  
  2. int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr,  
  3. void *(*start_rtn)(void *), void *restrict arg);  
  4.                        Returns: 0 if OK, error number on failure  

当pthread_create成功返回时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于定制各种不同的线程属性。若为NULL,则创建默认属性的线程。新创建的线程从start_rtn函数的地址开始执行,该函数只有一个无类型指针参数arg。如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg参数传入。pthread函数在调用失败时通常返回错误码。

         与创建进程一样,线程创建时并不能保证哪个线程会先运行:是新创建的线程还是调用线程。新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的未决信号集被清除。

直接上代码,简单明了。


  1. #include <pthread.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <unistd.h>  
  5. #include <string.h>  
  6.   
  7. // 线程ID  
  8. pthread_t       ntid;  
  9. // 互斥对象  
  10. pthread_mutex_t mutex;  
  11.   
  12. int             count;  
  13.   
  14. void printids(const char *s)  
  15. {  
  16.     pid_t   pid;  
  17.     pthread_t   tid;  
  18.   
  19.     pid = getpid();  
  20.     tid = pthread_self();  
  21.   
  22.     printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid,  
  23.         (unsigned int)tid, (unsigned int)tid);  
  24. }  
  25.   
  26. // 线程函数  
  27. void *thr_fn(void *arg)  
  28. {  
  29.     printids("new thread begin\n");  
  30.   
  31.     // 加锁  
  32.     pthread_mutex_lock(&mutex);  
  33.   
  34.     printids("new thread:");  
  35.   
  36.     int i=0;  
  37.     for ( ; i < 5; ++i )  
  38.     {  
  39.         printf("thr_fn runing %d\n", count++);  
  40.     }  
  41.   
  42.     // 释放互斥锁  
  43.     pthread_mutex_unlock(&mutex);  
  44.   
  45.     return ( (void*)100);  
  46. }  
  47.   
  48. int main(void)  
  49. {  
  50.     int err;  
  51.   
  52.     count = 0;  
  53.     // 初始化互斥对象  
  54.     pthread_mutex_init(&mutex, NULL);  
  55.   
  56.     // 创建线程  
  57.     err = pthread_create(&ntid, NULL, thr_fn, NULL);  
  58.     if ( 0 != err )  
  59.     {  
  60.         printf("can't create thread:%s\n", strerror(err));  
  61.     }  
  62.   
  63.     // sleep(5);  
  64.     pthread_mutex_lock(&mutex);    
  65.     printids("main thread:");  
  66.     int i=0;  
  67.     for ( ; i < 5; ++i )  
  68.     {  
  69.         printf("main runing %d \n", count++);  
  70.     }  
  71.     sleep(1);  
  72.     pthread_mutex_unlock(&mutex);  
  73.   
  74.     int **ret;  
  75.     pthread_join(ntid, (void**)ret);  
  76.     printf("thr_fn return %d\n", *ret);  
  77.   
  78.     pthread_mutex_destroy(&mutex);  
  79.   
  80.   
  81.     return 0;  
  82. }  

     
    这个例子,用到了pthread的数据结构:
    pthread_t,  这个结构来标识线程ID;
    pthread_mutex_t, 这个用来做互斥;


    用到了如下函数:
    pthread_self() :  获得线程自身的ID;

    pthread_create(&ntid, NULL, thr_fn, NULL): 线程创建函数
    原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void*(*start_routine)(void*),  void *arg)。
    tid : 新创建线程的线程ID;
    attr: 指定新创建线程的线程属性,为NULL即为使用默认属性;
    start_routine : 这是一个函数指针,用来指向线程函数;
    arg : 传递给线程函数的指针;    
    返回值 : 0代表成功。 失败,返回的则是错误号。

    pthread_join(ntid, (void*)ret):等待一个线程的结束   
    原型:int pthread_join(pthread_t thread, void **retval);
    thread : 需要等待的线程的ID;
    retval : 存放等待线程的返回值;
    返回值 : 0代表成功。 失败,返回的则是错误号。
    
    pthread_mutex_init(&mutex, NULL):初始化互斥锁,以动态方式创建互斥锁
    原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);
    mutex : 被初始化的锁对象;
    attr  : 指定新建互斥锁的属性。为NULL,则使用默认的互斥锁属性,默认属性为快速互斥锁。

    pthread_mutex_lock(&mutex)     : 加锁
    pthread_mutex_unlock(&mutex) : 释放锁

    pthread_mutex_destroy(&mutex): 销毁锁对象
    
    
    编译的时候,需要加上编译参数“-lpthread”。
    可以屏蔽pthread_mutex_lock(),pthread_mutex_unlock()看下没有互斥的结果。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值