欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

线程同步--线程间通信

程序员文章站 2023-01-24 21:14:16
一、线程同步  线程的同步方法跟其他下类似,我们可以用原子操作,可以用 mutex,lock 等。  ios 的原子操作函数是以 osatomic 开头的,...

一、线程同步

 线程的同步方法跟其他下类似,我们可以用原子操作,可以用 mutex,lock 等。

 ios 的原子操作函数是以 osatomic 开头的,比如:osatomicadd32, osatomicor32 等等。这些函数可以直接使用,因为它 们是原子操作。

 ios 中的 mutex 对应的是 nslock,它遵循 nslooking 协议,我们可以使用 lock, trylock, lockbeforedata:来加锁,用 unlock 来解锁。使用示例:

 bool moretodo = yes;

 nslock *thelock = [[nslock alloc] init];

 ...

 while (moretodo) {

 /* do another increment of calculation */ /* until there’s no more to do. */

if ([thelock trylock]) {

    /* update display used by all threads. */

    [thelock unlock]; }

}

我们可以使用指令 @synchronized 来简化 nslock 的使用,这样我们就不必显示编写创建 nslock,加锁并解锁相关代码。 - (void)mymethod:(id)anobj

{

    @synchronized(anobj) {

        // everything between the braces is protected by the @synchronized directive. }

    }

    还有其他的一些锁对象,比如:循环锁 nsrecursivelock,条件锁 nsconditionlock,分布式锁 nsdistributedlock 等等,在 这里就不一一介绍了,大家去看官方文档吧。

    用 nscodition 同步执行的顺序

    nscodition 是一种特殊类型的锁,我们可以用它来同步操作执行的顺序。它与 mutex 的区别在于更加精准,等待某个 nscondtion 的线程一直被 lock,直到其他线程给那个 condition 发送了信号。下面我们来看使用示例:

    某个线程等待着事情去做,而有没有事情做是由其他线程通知它的。

    [cocoacondition lock]; while (timetodowork <= 0)

        [cocoacondition wait];

    timetodowork--;

    // do real work here. [cocoacondition unlock];

    其他线程发送信号通知上面的线程可以做事情了:

    [cocoacondition lock]; timetodowork++; [cocoacondition signal]; [cocoacondition unlock];

    二、线程间通信

    线程在运行过程中,可能需要与其它线程进行通信。我们可以使用 nsobject 中的一些方法: 在应用程序主线程中做事情:

performselectoronmainthread:withobject:waituntildone: performselectoronmainthread:withobject:waituntildone:modes:

    在指定线程中做事情:

performselector:onthread:withobject:waituntildone: performselector:onthread:withobject:waituntildone:modes:

    在当前线程中做事情:

performselector:withobject:afterdelay: performselector:withobject:afterdelay:inmodes:

    取消发送给当前线程的某个消息

cancelpreviousperformrequestswithtarget: cancelpreviousperformrequestswithtarget:selector:object:

    如在我们在某个线程中下载数据,下载完成之后要通知主线程中更新界面等等,可以使用如下接口:- (void)mythreadmainmethod

    {

        nsautoreleasepool *pool = [[nsautoreleasepool alloc] init];

        // to do something in your thread job

        ...

        [self performselectoronmainthread:@selector(updateui) withobject:nil waituntildone:no]; [pool release];

    }

    runloop

    说到 nsthread 就不能不说起与之关系相当紧密的 nsrunloop。run loop 相当于 win32 里面的消息循环机制,它可以让你 根据事件/消息(鼠标消息,键盘消息,计时器消息等)来调度线程是忙碌还是闲置。 系统会自动为应用程序的主线程生成一个与之对应的 run loop 来处理其消息循环。在触摸 uiview 时之所以能够激发 touchesbegan/touchesmoved 等等函数被调用,就是因为应用程序的主线程在 uiapplicationmain 里面有这样一个 run loop 在分发 input 或 timer 事件。