管道的三种使用方案中,唯一正确而安全的使用方法

简介: 管道的三种使用方案中,唯一正确而安全的使用方法

系统自带的管道方法:

全局变量:

NSPipe * pipe = [NSPipe pipe] ;

NSFileHandle *pipeReadHandle = [pipe fileHandleForReading] ;

int pipeReadFd = [[pipe fileHandleForReading] fileDescriptor], fd];

int pipeWriteFd = [[pipe fileHandleForWriting] fileDescriptor], fd];

写管道处,注意这个函数是无返回的函数,无法判断管道异常:

[self.pipeWriteFd writeData: [@”send” dataUsingEncoding: NSASCIIStringEncoding]]; 见我的文章管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用 (http://blog.csdn.net/jia12216/article/details/47360637

它的缺点也很显然,线程被杀,管道资源被回收时,你访问该管道,会出现管道破裂的系统级崩溃。详细见我的文章。

Signal 13 was raised(SIGPIPE管道破裂)

http://blog.csdn.net/jia12216/article/details/50844013


所以还时用系统级别的管道最安全,可以通过写管道是否可以写来判断管道是否可用。

这样使用申请管道也是错误的,因为你的线程申请的管道,在外部要可以用,肯定要能用,你申请个局部变量,等你离开线程时,你再使用管道,你就访问了空指针,造成管道破裂崩溃。下面是例子

int pipeSNO[2];

pipeSNO[0] = -1;

pipeSNO[1] = -1;

pipe(pipeSNO);

self.fdGuardModifyWaitTimeReadPipe = pipeSNO[0];

self.fdGuardModifyWaitTimeWritePipe = pipeSNO[1];

int set = 1;

setsockopt(self.fdGuardModifyWaitTimeReadPipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

int write = 1;

setsockopt(self.fdGuardModifyWaitTimeWritePipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&write, sizeof(int));

看来你向获得强大的功能,那么你就要从操作系统层做起,并且自己负责管道的申请和释放,不受系统ARC自动管理内存控制。下面是正确而强大的使用管道的部分例子,

申请管道部分:

if(self.fdGuardPipeHead != nil)

{

close(self.fdGuardModifyWaitTimeReadPipe);

close(self.fdGuardModifyWaitTimeWritePipe);

free(self.fdGuardPipeHead);

}

self.fdGuardPipeHead = malloc(2 * sizeof(int));

_fdGuardPipeHead[0] = -1;

_fdGuardPipeHead[1] = -1;

pipe(_fdGuardPipeHead);

self.fdGuardModifyWaitTimeReadPipe = _fdGuardPipeHead[0];

self.fdGuardModifyWaitTimeWritePipe = _fdGuardPipeHead[1];

int set = 1;

setsockopt(self.fdGuardModifyWaitTimeReadPipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));

int write = 1;

setsockopt(self.fdGuardModifyWaitTimeWritePipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&write, sizeof(int));

[self creatSocketConnection];


发送于异常判断

//通过长连接的监控管道发送char *格式的消息

-(BOOL)sendMessageBySocketMonitorPipeWithCharArr : (const char *)message

{

NSUInteger len = 0;

len = strlen(message);

if(0 == len)

{

return YES;

}

unsigned char input_msg[BUFFER_SIZE] = {0};

memcpy(input_msg, message, len);;

@try {

long ret = write(self.fdWritePipe, input_msg, len);

if(ret != len)

{

[self processSocketPipeClosed];

return NO;

}

else

{

return YES;

}

}

@catch (NSException *exception) {

FLDDLogInfo(@”exception:%@”, exception);

[self processSocketPipeClosed];

return NO;

}

@finally {

}

}


关闭管道的操作

-(void)processSocketPipeClosed

{

FLDDLogDebug(@”函数”);

if(self.socketThreadPipeHead != nil)

{

close(self.fdReadPipe);

close(self.fdWritePipe);

free(self.socketThreadPipeHead);

}

self.socketThreadPipeHead = malloc(2 * sizeof(int));
_socketThreadPipeHead[0] = -1;
_socketThreadPipeHead[1] = -1;
pipe(_socketThreadPipeHead);
self.fdReadPipe = _socketThreadPipeHead[0];
self.fdWritePipe = _socketThreadPipeHead[1];
int setPipe = 1;
setsockopt(self.fdReadPipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&setPipe, sizeof(int));
int writePipe = 1;
setsockopt(self.fdWritePipe, SOL_SOCKET, SO_NOSIGPIPE, (void *)&writePipe, sizeof(int));
if(![self sendMessageByPipeWithCharArr : g_guardThreadCheckIfNormal])
{
    //守护线程的监控管道被系统关闭,需要建立守护线程时立刻重新建立长连接,防止无法通过监控管道控制守护线程
    _connectTime = (long long)[[NSDate date] timeIntervalSince1970] - SOCKET_CONNECT_ABORT_WAIT_TIME - 1;
    _currentSocketThreadDic = nil;
    _socketThreadDic = nil;
    if(self.fd > 0)
    {
        close(self.fd);
    }
    self.socketConnectStat = SOCKECT_CONNECT_ABNORMAL;
}
else
{
    [self creatSocketConnection];
}

}

目录
相关文章
|
运维 Shell
运维(13)- shell输入输出
运维(13)- shell输入输出
118 0
|
11月前
|
NoSQL 前端开发 MongoDB
Mock神器:Easy-Mock 私有化部署及使用介绍
Easy-Mock 是一个非常实用的模拟数据工具,尤其在前后端分离开发的场景中,可以极大地提高前端开发效率。通过将 Easy-Mock 部署为私有化服务,你可以完全掌控模拟数据的生成和管理,同时保障数据的安全性和隐私性。
680 44
|
人工智能 监控 物联网
探索信息技术的前沿:推动社会进步与创新的强大力量
探索信息技术的前沿:推动社会进步与创新的强大力量
413 3
|
机器学习/深度学习 供应链 监控
ERP系统中的供应链可视化与智能预测解析
【7月更文挑战第25天】 ERP系统中的供应链可视化与智能预测解析
544 5
|
传感器 数据采集 监控
ERP系统中的生产过程监控与质量管理解析
【7月更文挑战第25天】 ERP系统中的生产过程监控与质量管理解析
587 0
ERP系统中的生产过程监控与质量管理解析
|
机器学习/深度学习 存储 运维
Elasticsearch 中的异常检测机制与应用场景
【8月更文第28天】随着数据量的增长和业务复杂性的提升,实时监测和分析大量数据成为一项挑战。Elasticsearch 不仅是一个高性能的全文搜索引擎,也是一个灵活的数据存储和分析平台。通过集成机器学习(ML)功能,Elasticsearch 能够实现更高级的数据分析任务,如异常检测。
411 0
|
负载均衡 监控 前端开发
在Linux中,如何配置负载均衡器以分配网络流量?
在Linux中,如何配置负载均衡器以分配网络流量?
|
JavaScript 前端开发 算法
JavaScript 中 callee 与 caller 的作用
JavaScript 中 callee 与 caller 的作用
411 2
|
Shell Linux C语言
【Shell 命令集合 系统设置 】⭐Linux 显示系统的时钟时间 clock命令 使用指南
【Shell 命令集合 系统设置 】⭐Linux 显示系统的时钟时间 clock命令 使用指南
316 0
【Shell 命令集合 系统设置 】⭐Linux 显示系统的时钟时间 clock命令 使用指南
|
数据采集 算法 计算机视觉
基于RT-Thread摄像头车牌图像采集系统
该项目使用AB32VG1开发板基于RT-thread操作系统,结合ov7670摄像头捕获图像,并通过串口以RGB565格式传输到PC进行图像识别。然而,开发板实际可用RAM仅为70k,低于预期,导致无法在板上进行图像处理。原本计划的LCD屏幕因IO口不足而放弃,但保留了相关SPI代码。目前,摄像头数据采集和串口发送功能已完成,可正常工作。硬件包括csi接口的ov7670摄像头、PL2302串口工具。软件部分有详细的流程图和关键代码展示,其中串口通信速度限制为115200bps,低于上位机接收能力,造成效率不高。项目还展示了部分演示结果。
254 5