iOS 多线程

iOS 多线程系列 -- pthread

2017-06-27  本文已影响193人  shannoon

iOS 多线程系列 -- 基础概述
iOS 多线程系列 -- pthread
iOS 多线程系列 -- NSThread
iOS 多线程系列 -- GCD全解一(基础)
iOS 多线程系列 -- GCD全解二(常用方法)
iOS 多线程系列 -- GCD全解三(进阶)
iOS 多线程系列 -- NSOperation
测试Demo的GitHub地址

1. pthread概述


2. pthread中常用API

2.1 pthread_create

int pthread_create(pthread_t _Nullable * _Nonnull __restrict, const pthread_attr_t * _Nullable __restrict,void * _Nullable (* _Nonnull)(void * _Nullable),void * _Nullable __restrict);

2.2 pthread_join

int pthread_join(pthread_t , void * _Nullable * _Nullable)

2.3 pthread_detach

int pthread_detach(pthread_t);

2.4 pthread_kill

int pthread_kill(pthread_t, int);
  - (void)testThreadLife:(pthread_t)thread
{
    int kill_ret = pthread_kill(thread,0);// 系统定义的信号量宏,如:SIGUSR2,
    if(kill_ret == ESRCH)
        NSLog(@"指定的线程不存在或者是已经终止\n");
    else if(kill_ret == EINVAL)
        NSLog(@"调用传递一个无用的信号\n");
    else
        NSLog(@"线程存在\n");

}

2.5 线程取消相关的pthread函数

2.5.1 pthread_cancel
int pthread_cancel(pthread_t) __DARWIN_ALIAS(pthread_cancel);
2.5.2 pthread_setcancelstate
int pthread_setcancelstate(int , int * _Nullable)
2.5.3 pthread_setcanceltype
int pthread_setcanceltype (int type, int *oldtype) 
void * cancelRun (void *prama)
{
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); // 忽略取消信号,即使收到其他线程调用pthread_cancel,也会继续执行任务
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);// 设置收到取消信号,立即取消
    if (!prama) {
        NSLog(@"run1 prama = null");
    } else {
        NSLog(@"run1 prama = %d\n", (int)(*((int*)prama)));
    }
    for (int i = 0; i<5000; i++) {
        NSLog(@"---run1--%d---%@",i,[NSThread currentThread]);
    }
    return &a;

}
2.5.4 pthread_testcancel 设置取消点

3 API总结

3.1 操作函数

pthread_create():创建一个线程
pthread_exit():终止当前线程
pthread_cancel():中断另外一个线程的运行
pthread_join():阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init():初始化线程的属性
pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate():获取脱离状态的属性
pthread_attr_destroy():删除线程的属性
pthread_kill():向线程发送一个信号
pthread_equal(): 对两个线程的线程标识号进行比较
pthread_detach(): 分离线程
pthread_self(): 查询线程自身线程标识号

3.2 同步函数

数据类型:
方法
其他方法

pthread_cond_init():初始化条件变量
pthread_cond_destroy():销毁条件变量
pthread_cond_signal(): 唤醒第一个调用pthread_cond_wait()而进入睡眠的线程
pthread_cond_wait(): 等待条件变量的特殊条件发生
pthread_key_create(): 分配用于标识进程中线程特定数据的键
pthread_setspecific(): 为指定线程特定数据键设置线程特定绑定
pthread_getspecific(): 获取调用线程的键绑定,并将该绑定存储在 value 指向的位置中
pthread_key_delete(): 销毁现有线程特定数据键
pthread_attr_getschedparam();获取线程优先级
pthread_attr_setschedparam();设置线程优先级

4. 使用示例:

void即“无类型”,void *则为“无类型指针”,可以指向任何数据类型

- (void)testCreatJoinDetach
{
    pthread_t thread1;
    pthread_attr_t att;
    pthread_attr_init(&att);
    int result = pthread_create(&thread1, &att, run1, nil);//创建一个线程
    if (result == 0) {
        NSLog(@"创建线程 OK");
    } else {
        NSLog(@"创建线程失败 %d", result);
    }
    NSLog(@"111(*thread1).__sig = %ld ,(*thread1).__opaque = %s, thread1 = %p",(*thread1).__sig ,(*thread1).__opaque , thread1);
    
    NSLog(@"before pthread_join ");
    void * thread1Return;
    pthread_join(thread1, &thread1Return);//当前线程被阻塞,等待线程1结束后恢复
    NSLog(@"after pthread_join ; thread1Return = %zd ",(!thread1Return) ? 0 : (int)(*((int *)thread1Return)));

    pthread_t thread2;
    int a = 2;
    pthread_create(&thread2, NULL, (void *)run2, &a);
    pthread_detach(thread2); // 或者在run2中调用pthread_detach(pthread_self());
}

int a = 88;
void * run1 (void *prama)
{
    if (!prama) {
        NSLog(@"run1 prama = null");
    } else {
        NSLog(@"run1 prama = %d\n", (int)(*((int*)prama)));
    }
    for (int i = 0; i<3; i++) {
        NSLog(@"---run1--%d---%@",i,[NSThread currentThread]);
    }
    return &a;
}

void run2 (void *prama)
{
    if (!prama) {
        NSLog(@"run2 prama = null");
    } else {
        NSLog(@"run2 prama = %d\n", (int)(*((int*)prama)));
    }
    for (int i = 0; i<3; i++) {
        NSLog(@"--run2---%d---%@",i,[NSThread currentThread]);
    }
//    pthread_detach(pthread_self());
}

打印结果如下:

**2017-06-27 11:28:42.393 Test - ****多线程****[38965:5126933] pthread_join ****前**
**2017-06-27 11:28:42.394 Test - ****多线程****[38965:5127082] ---run--0---<NSThread: 0x600000271980>{number = 3, name = (null)}**
**2017-06-27 11:28:42.394 Test - ****多线程****[38965:5127082] ---run--1---<NSThread: 0x600000271980>{number = 3, name = (null)}**
**2017-06-27 11:28:42.394 Test - ****多线程****[38965:5127082] ---run--2---<NSThread: 0x600000271980>{number = 3, name = (null)}**
**2017-06-27 11:28:42.395 Test - ****多线程****[38965:5126933] pthread_join ****后**** thread1Return = 0**
**prama from thread2 2**
**2017-06-27 11:28:42.395 Test - ****多线程****[38965:5127083] --run2---0---<NSThread: 0x60800026f7c0>{number = 4, name = (null)}**
**2017-06-27 11:28:42.395 Test - ****多线程****[38965:5127083] --run2---1---<NSThread: 0x60800026f7c0>{number = 4, name = (null)}**

**2017-06-27 11:28:42.396 Test - ****多线程****[38965:5127083] --run2---2---<NSThread: 0x60800026f7c0>{number = 4, name = (null)}**

5. 参考资料

iOS开发 - 多线程实现方案之Pthread篇

linux多线程全面解析

pthread_cancel引起的死锁

上一篇 下一篇

猜你喜欢

热点阅读