线程之间的通信、加锁解锁

#import "ViewController.h"

@interface ViewController ()

//NSLock
//既可以对基本数据类型的数据加锁,也可以对对象加锁,是万能的
@property(nonatomic,strong) NSLock *lock;



@end

@implementation ViewController

//服务器的余票数
static NSInteger count = 5000;



//买票方法
-(void)buyTicket
{
    [self.lock lock];
    count --;
    NSLog(@"%ld",count);
    [_lock unlock];
}

//给lock懒加载,分配内存
-(NSLock *)lock
{
    if (_lock == nil) {
        _lock = [[NSLock alloc] init];
    }
    return _lock;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    /*
    //创建
    
    // 创建自定义并行队列
    dispatch_queue_t concurentQueue = dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);
    
    //添加任务
    dispatch_async(concurentQueue, ^{
        NSLog(@"任务一");
        
    });
    
    dispatch_async(concurentQueue, ^{
        NSLog(@"任务二");
    });
    
    //执行完现在的任务才执行后面的任务
    dispatch_barrier_async(concurentQueue, ^{
        NSLog(@"我的这个任务执行了才执行后面的任务");
    });
    
    
    dispatch_async(concurentQueue, ^{
        NSLog(@"任务三");
    });
    
    
    //延迟任务
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), concurentQueue, ^{
        NSLog(@"我是延迟任务");
    });
    
    //重复执行多次
    dispatch_apply(3, concurentQueue, ^(size_t t) {
        NSLog(@"我的这个任务要执行多次哦,%ld",t);
    });
    
    
    
    dispatch_async(dispatch_get_main_queue(), ^{
#pragma mark--------------获取现在线程(number,name)
        //注意:只要number不是1,都是子线程,number的值表示优先级。
        NSLog(@"%@",[NSThread currentThread]);
        
    });
    
    
    dispatch_queue_t globleQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(globleQueue, ^{
        NSLog(@"%@",[NSThread currentThread] );
    });
    */
    
    
#pragma mark---------------线程间通信
    
    //主线程
    
//    //主线程到子线程
//    [self performSelectorInBackground:@selector(subThreadAction) withObject:nil];
//    
//    //方式二:直接在队列中调用从主对列中添加任务的方法
//    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//       
//        dispatch_async(dispatch_get_main_queue(), ^{
//           
//            NSLog(@"%@",[NSThread currentThread]);
//
//        });
//    });
//    
 
    //原子性的setter和getter方法
    
//    @property (automic,strong)NSString *name;
//    
//    //setter
//    
//    -(void)setName:(name)
//    {
//        @synchronized(_name)//同步锁,保证同时只有一个线程可以访问此对象
                            //注意:基本数据类型不能加锁,只有对象才能加锁
//        {
//            if (_name != name) {
//                [_name release];
//                _name = [name retain];
//            }
//        }
//    }
    
    //getter
//    -(NSString *)name
//    {
//        @synchronized(_name){
//        return [[_name retain] autorelease];
//        }
//    }
    
    
    
    
#pragma mark-------------多线程访问服务器买票
    
    //创建一个并行队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
    
    __weak typeof(self) temp = self;
    dispatch_async(concurrentQueue, ^{
        for (int  i = 0;i < 1000; i ++) {
            [temp buyTicket];
        }
       
    });
    
    dispatch_async(concurrentQueue, ^{
        for (int  i = 0;i < 1000; i ++) {
            [temp buyTicket];
        }
        
    });

    
}

#pragma mark---------------一般方法回到主线程
/*
//子线程方法
-(void)subThreadAction
{
    NSLog(@"%@",[NSThread currentThread]);
    
    NSString *string = @"阿斯顿";
   
 //方式一:
    //子线程回到主线程
 
    waitUntilDone是YES的话,子线程结束后 会阻塞主线程 走callBack方法
    如果是NO的话 就不会阻塞 主线程
 
    [self performSelectorOnMainThread:@selector(mainThreadAction:) withObject:string waitUntilDone:YES];
}

//主线程方法
-(void)mainThreadAction:(id)sender
{
    NSLog(@"%@",sender);
    NSLog(@"%@",[NSThread currentThread]);
}



- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
*/

### 嵌入式 Linux 环境下的多线程通信方法 #### 一、共享内存区 在同一进程中创建的不同线程可以访问相同的地址空间,这意味着它们可以直接通过读写同一块内存区域来交换数据。这种方式效率高,因为不需要额外的数据复制操作[^2]。 ```c #include <pthread.h> int global_var; // 全局变量作为共享资源 void* thread_function(void *arg){ int local; // 对global_var的操作... } ``` #### 二、互斥(Mutex) 为了防止多个线程同时修改相同的数据造成竞争条件,可利用互斥量保护临界区内的代码执行。当某个线程进入该部分时会定此互斥体;离开之前解锁以便其他等待中的线程能够继续运行[^1]。 ```c pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 加锁前后的代码片段 pthread_mutex_lock(&mutex); /* critical section */ pthread_mutex_unlock(&mutex); ``` #### 三、信号量(Semaphore) 除了简单的互斥外,有时还需要协调不同任务间的顺序关系或限制某些活动的数量上限,则可以通过V操作增加计数值而P操作减少其值来进行同步控制[^3]。 ```c sem_t sem; sem_init(&sem, 0, 1); // 使用信号量进行同步 sem_wait(&sem); /* wait() decrements the semaphore value by one. If its value is less than zero before this operation, then the calling process shall be blocked until it can successfully decrement the count. */ /* protected code here */ sem_post(&sem); /* post() increments the semaphore value by one and wakes up any threads that are waiting on the semaphore. */ ``` #### 四、条件变量(Condition Variable) 如果希望在线程之间传递更加复杂的事件通知信息而不是仅仅依靠标志位的话,那么就可以考虑使用条件变量配合互斥一起工作。一个典型的场景是在生产者消费者模型中用来唤醒处于休眠状态的接收方去处理新到来的消息队列项。 ```c pthread_cond_t cond = PTHREAD_COND_INITIALIZER; pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; while (condition != true) { pthread_cond_wait(&cond, &mtx); } // 当满足特定条件时发出信号给另一个/些正在等待的线程 pthread_cond_signal(&cond); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值