iOS线程通信和进程通信的例子(NSMachPort和NSTask,NSPipe)

转载 2017年01月03日 23:00:55

转载:http://blog.csdn.net/yxh265/article/details/51483822

iOS线程间的通信

iOS中,两个线程之间要想互相通信,可以使用:NSMachPort 
下面是例子

#define kMsg1 100
#define kMsg2 101

- (void)viewDidLoad {
    [super viewDidLoad];

    //1. 创建主线程的port
    // 子线程通过此端口发送消息给主线程
    NSPort *myPort = [NSMachPort port];

    //2. 设置port的代理回调对象
    myPort.delegate = self;

    //3. 把port加入runloop,接收port消息
    [[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode];

    NSLog(@"---myport %@", myPort);
    //4. 启动次线程,并传入主线程的port
    MyWorkerClass *work = [[MyWorkerClass alloc] init];
    [NSThread detachNewThreadSelector:@selector(launchThreadWithPort:)
                             toTarget:work
                           withObject:myPort];
}
- (void)handlePortMessage:(NSMessagePort*)message{

    NSLog(@"接到子线程传递的消息!%@",message);

    //1. 消息id
    NSUInteger msgId = [[message valueForKeyPath:@"msgid"] integerValue];

    //2. 当前主线程的port
    NSPort *localPort = [message valueForKeyPath:@"localPort"];

    //3. 接收到消息的port(来自其他线程)
    NSPort *remotePort = [message valueForKeyPath:@"remotePort"];

    if (msgId == kMsg1)
    {
        //向子线的port发送消息
        [remotePort sendBeforeDate:[NSDate date]
                             msgid:kMsg2
                        components:nil
                              from:localPort
                          reserved:0];

    } else if (msgId == kMsg2){
        NSLog(@"操作2....\n");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

MyWorkerClass

#import "MyWorkerClass.h"

@interface MyWorkerClass() <NSMachPortDelegate> {
    NSPort *remotePort;
    NSPort *myPort;
}
@end

#define kMsg1 100
#define kMsg2 101

@implementation MyWorkerClass


- (void)launchThreadWithPort:(NSPort *)port {

    @autoreleasepool {

        //1. 保存主线程传入的port
        remotePort = port;

        //2. 设置子线程名字
        [[NSThread currentThread] setName:@"MyWorkerClassThread"];

        //3. 开启runloop
        [[NSRunLoop currentRunLoop] run];

        //4. 创建自己port
        myPort = [NSPort port];

        //5.
        myPort.delegate = self;

        //6. 将自己的port添加到runloop
        //作用1、防止runloop执行完毕之后推出
        //作用2、接收主线程发送过来的port消息
        [[NSRunLoop currentRunLoop] addPort:myPort forMode:NSDefaultRunLoopMode];



        //7. 完成向主线程port发送消息
        [self sendPortMessage];


    }
}

/**
 *   完成向主线程发送port消息
 */
- (void)sendPortMessage {

    NSMutableArray *array  =[[NSMutableArray alloc]initWithArray:@[@"1",@"2"]];
    //发送消息到主线程,操作1
    [remotePort sendBeforeDate:[NSDate date]
                         msgid:kMsg1
                    components:array
                          from:myPort
                      reserved:0];

    //发送消息到主线程,操作2
    //    [remotePort sendBeforeDate:[NSDate date]
    //                         msgid:kMsg2
    //                    components:nil
    //                          from:myPort
    //                      reserved:0];
}


#pragma mark - NSPortDelegate

/**
 *  接收到主线程port消息
 */
- (void)handlePortMessage:(NSPortMessage *)message
{
    NSLog(@"接收到父线程的消息...\n");

    //    unsigned int msgid = [message msgid];
    //    NSPort* distantPort = nil;
    //
    //    if (msgid == kCheckinMessage)
    //    {
    //        distantPort = [message sendPort];
    //
    //    }
    //    else if(msgid == kExitMessage)
    //    {
    //        CFRunLoopStop((__bridge CFRunLoopRef)[NSRunLoop currentRunLoop]);
    //    }
}

@end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

以上就可以完成一个线程间的数据通信。

iOS进程间的通信(越狱时用到)

先创建一个命令行工程,建一个简单的子项目。名为:taskchild

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#include <stdio.h>


int main (int argc, const char * argv[])
{

    NSLog(@"receive value arg %d %s %s", argc, argv[0], argv[1]);

    sleep(10);

    // insert code here...
    printf("Hello, World!\n");
    NSLog(@"Hello, World");
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

再创建一个有界面的主项目。进程通信部分代码。需要引用头文件:NSTask.h见下面的引用

    NSString* string = [[NSBundle mainBundle] pathForResource:@"taskchild" ofType:nil];//taskchild是所要启动的名字二进制文件名,上面建的子项目。
    NSLog(@"%@",string);

    NSTask *task;
    task = [[NSTask alloc ]init];
    [task setLaunchPath:string];

    NSLog(@"This is NSTask with ping command......\n");
    NSArray *arguments;
    arguments = [NSArray arrayWithObjects:@"22", nil];
    [task setArguments:arguments];

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput:pipe];

    NSFileHandle *file;
    file = [pipe fileHandleForReading];

    [task launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"get child value :%@",string);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

引用

RunLoops 
NSTask-4-iOS


iOS线程通信和进程通信的例子(NSMachPort和NSTask,NSPipe)

iOS线程间的通信iOS中,两个线程之间要想互相通信,可以使用:NSMachPort 下面是例子#define kMsg1 100 #define kMsg2 101- (void)viewDidL...
  • yxh265
  • yxh265
  • 2016年05月23日 18:33
  • 5770

[消息传递之五]-NSMatchPort练习

#import @interface ViewController : UIViewController @property (nonatomic) NSMutableArray* NotArra...
  • liyanq528
  • liyanq528
  • 2016年01月10日 10:55
  • 295

管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用

找了很久也没有找到NSPipe在IOS方面的常规使用()。我试了半天终于找到它的正常的使用方法,我想对很多想使用管道会有很大的帮助。阿门,看来我是第一吃螃蟹的人。 进程和线程间四大通信机制:管道,信...
  • jia12216
  • jia12216
  • 2015年12月01日 16:57
  • 3395

使用NSThread创建线程,执行NSTask,但是异步读取pipe的时候出错

使用NSThread创建线程,执行NSTask,但是异步读取pipe的时候出错    想要创建一个线程,然后执行shell命令,并且是异步的读取shell命令返回的信...
  • yuanya
  • yuanya
  • 2014年12月05日 13:19
  • 1189

基于runloop的线程保活、销毁与通信

首先看一段AF2.x经典代码: + (NSThread *)networkRequestThread { static NSThread *_networkRequestThread = ni...
  • App_IOS
  • App_IOS
  • 2017年02月07日 14:28
  • 1248

关于NSTask使用的一些心得体会

NSTask是MAC OS X用来执行系统命令的一个类库,作用类似php的exec,最近在使用过程中遇到诸多不顺,结合以前的经验,记录一下,方便后来人 1.推荐使用Taskit 功欲善其事,必先利...
  • yuanya
  • yuanya
  • 2014年10月11日 22:34
  • 1808

多线程之同步线程通信小例子

最近在学习多线程的时候,看到这样的一个问题:有两个线程,一个是子线程,一个是主线程,子线程运行10次,接着主线程运行20次,接着子线程运行10,主线程运行20次,依次交替循环20次。刚开始看到这个问题...
  • zknxx
  • zknxx
  • 2016年11月15日 23:21
  • 611

[ios版本]AR 现实增强之高通Vuforia QCAR SDK (二)

[ios版本]AR 现实增强之高通Vuforia QCAR SDK (二) 这章会比较简单。就是换上麦叔叔,不是肯叔叔的logo,然后对着丫照啊照,就能看到茶壶了。为啥是茶壶不是汉堡?因...
  • zrhloveswallow
  • zrhloveswallow
  • 2014年07月10日 12:04
  • 4556

[ios版本]AR 现实增强之高通Vuforia

古人常曰饮水思源,知恩图报。由于近期工作需要,需要学习AR和图像识别。但是国内资料真的很少,基本都是拷贝粘贴。为数不多有用的信息就是一篇关于高通的库,但是是安卓版本的。有兴趣的自己过去看下,由于我需要...
  • mrandy
  • mrandy
  • 2015年12月16日 23:45
  • 1661

Java线程池例子

在做很多高并发应用的时候,单线程的瓶颈已经满足不了我们的需求,此时使用多线程来提高处理速度已经是比较常规的方案了。在使用多线程的时候,我们可以使用线程池来管理我们的线程,至于使用线程池的优点就不用说了...
  • catoop
  • catoop
  • 2015年12月04日 23:16
  • 13391
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS线程通信和进程通信的例子(NSMachPort和NSTask,NSPipe)
举报原因:
原因补充:

(最多只允许输入30个字)