首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    CreatePipe匿名管道通信

    大家好,又见面了,我是你们的朋友全栈君。 管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。     匿名管道实施细则     匿名管道由CreatePipe()函数创建,该函数在创建匿名管道的同时返回两个句柄:管道读句柄和管道写句柄。CreatePipe()的函数原型为:   BOOL CreatePipe(PHANDLE hReadPipe, // 指向读句柄的指针    PHANDLE hWritePipe, // 指向写句柄的指针    LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全属性的指针    DWORD nSize // 管道大小   );     通过hReadPipe和hWritePipe所指向的句柄可分别以只读、只写的方式去访问管道。在使用匿名管道通信时,服务器进程必须将其中的一个句柄传送给客户机进程。句柄的传递多通过继承来完成,服务器进程也允许这些句柄为子进程所继承。除此之外,进程也可以通过诸如DDE或共享内存等形式的进程间通信将句柄发送给与其不相关联的进程。     在调用CreatePipe()函数时,如果管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。管道服务器可调用DuplicateHandle()函数改变管道句柄的继承。管道服务器可以为一个可继承的管道句柄创建一个不可继承的副本或是为一个不可继承的管道句柄创建一个可继承的副本。CreateProcess()函数还可以使管道服务器有能力决定子进程对其可继承句柄是全部继承还是不继承。     在生成子进程之前,父进程首先调用Win32 API SetStdHandle()使子进程、父进程可共用标准输入、标准输出和标准错误句柄。当父进程向子进程发送数据时,用SetStdHandle()将管道的读句柄赋予标准输入句柄;在从子进程接收数据时,则用SetStdHandle()将管道的写句柄赋予标准输出(或标准错误)句柄。然后,父进程可以调用进程创建函数CreateProcess()生成子进程。如果父进程要发送数据到子进程,父进程可调用WriteFile()将数据写入到管道(传递管道写句柄给函数),子进程则调用GetStdHandle()取得管道的读句柄,将该句柄传入ReadFile()后从管道读取数据。     如果是父进程从子进程读取数据,那么由子进程调用GetStdHandle()取得管道的写入句柄,并调用WriteFile()将数据写入到管道。然后,父进程调用ReadFile()从管道读取出数据(传递管道读句柄给函数)。     在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。     匿名管道并不支持异步读、写操作,这也就意味着不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped参数也将被忽略。匿名管道将在读、写句柄都被关闭后退出,也可以在进程中调用CloseHandle()函数来关闭此句柄   /   匿名管道程序示例     总的来说,匿名管道程序是比较简单的。在下面将要给出的程序示例中,将由父进程(管道服务器)创建一个子进程(管道客户机),子进程回见个其全部的标准输出发送到匿名管道中,父进程再从管道读取数据,一直到子进程关闭管道的写句柄。其中,匿名管道服务器程序的实现清单如下:   STARTUPINFO si;   PROCESS_INFORMATION pi;   char ReadBuf[100];   DWORD ReadNum;   HANDLE hRead; // 管道读句柄   HANDLE hWrite; // 管道写句柄   BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 创建匿名管道   if (bRet

    01

    理解数据库连接池底层原理之手写实现前言对数据库连接池的一点思考写一个迷你版数据库连接池

    数据库连接池的基本思想是:为数据库连接建立一个“缓冲池”,预先在池中放入一定数量的数据库连接管道,需要时,从池子中取出管道进行使用,操作完毕后,在将管道放入池子中,从而避免了频繁的向数据库申请资源,释放资源带来的性能损耗。在如今的分布式系统当中,系统的QPS瓶颈往往就在数据库,所以理解数据库连接池底层构造原理与设计思想是很有益处的。我们常用的数据库连接池有C3P0,DBCP,Druid等,下面我们就来分析下数据库连接池应该有些什么,以及手写一个迷你版的数据库连接池!

    01

    OushuDB 小课堂丨数据管道测试自动化的最佳实践

    数据集成过程与任何其他软件一样受益于自动化测试。然而,找到一个具有一套合适的自动测试的数据管道项目是罕见的。即使一个项目有很多测试,它们通常也是非结构化的,不传达其目的,并且难以运行。一个特点数据管道开发是频繁发布高质量数据,以获得用户反馈和接受。在每次数据管道迭代结束时,预计下一阶段的数据都是高质量的。自动测试对于数据管道的集成测试至关重要。在高度迭代和适应性强的开发环境中,手动测试是不切实际的。手动数据测试的主要问题首先,它花费的时间太长,是管道频繁交付的关键抑制因素。主要依赖手动测试的团队最终会将测试推迟到专门的测试期,允许错误积累。其次,手动数据管道测试不足以进行回归测试。数据管道测试的自动化需要初步规划和持续的勤奋,但一旦技术团队采用自动化,项目的成功就更有保证。数据管道的变体提取、转换和加载(ETL)提取、加载和转换(ELT)数据湖,数据仓库管道实时管道机器学习管道用于测试自动化考虑的数据管道组件数据管道由几个组件组成,每个组件负责特定任务。数据管道的元素包括:数据来源:数据的来源数据摄取:从数据源收集数据的过程数据转换:将收集的数据转换为可用于进一步分析的格式的过程数据验证/验证:确保数据准确和一致的过程数据存储:将转换和验证的数据存储在数据仓库或数据湖中的过程数据分析:分析存储数据以识别模式、趋势和见解的过程自动化数据管道测试的最佳实践什么以及何时自动化(甚至如果您需要自动化)是测试(或开发)团队的关键决策。为自动化选择合适的产品特性在很大程度上决定了自动化的成功。在自动测试数据管道时,最佳实践包括:定义明确而具体的测试目标:在开始测试之前,必须定义您希望通过测试实现的目标。这样做将帮助您创建有效、高效的测试,提供有价值的见解。测试数据管道的所有工作流程:数据管道通常由几个组件组成:数据摄取、处理、转换和存储。重要的是要测试每个组件,以确保数据通过管道的适当和平稳流动。使用可信的测试数据:在测试数据管道时,使用模拟现实世界场景的现实数据很重要。这将有助于识别处理不同数据类型时可能出现的任何问题。使用有效的工具实现自动化:这可以通过测试框架和工具来实现。定期监控管道:即使在测试完成后,也必须定期监控管道,以确保其按预期工作。这将有助于在问题成为关键问题之前识别它们。让利益相关者参与:让数据分析师、数据工程师和业务用户等利益相关者参与测试过程。这将有助于确保测试对所有利益相关者都具有相关性和价值。维护文档:维护描述测试、测试用例和测试结果的文档很重要。这将有助于确保测试可以随着时间的推移进行复制和维护。小心;应避免自动更改不稳定特征。今天,任何已知的业务工具或一组方法/流程都不能被视为数据管道的完整端到端测试。考虑您的测试自动化目标数据管道测试自动化被描述为使用工具来控制1)测试执行,2)将实际结果与预测结果进行比较,以及3)设置测试先决条件和其他测试控制和测试报告功能。一般来说,测试自动化涉及使用正式测试过程的现有手动过程自动化。虽然手动数据管道测试可以揭示许多数据缺陷,但它们既费力又耗时。此外,手动测试在检测某些缺陷方面可能无效。数据管道自动化涉及开发测试程序,否则必须手动执行。一旦测试自动化,它们可以快速重复。对于使用寿命长的数据管道来说,这通常是最具成本效益的方法。在管道的生命周期中,即使是小的修复或增强也可能导致之前工作的功能中断。在数据管道开发中集成自动化测试带来了一系列独特的挑战。当前的自动化软件开发测试工具不容易适应数据库和数据管道项目。各种各样的数据管道架构使这些挑战进一步复杂化,因为它们涉及多个数据库,需要对数据提取、转换、加载进行特殊编码,数据清理、数据聚合和数据丰富。测试自动化工具可能很昂贵,通常与手动测试一起使用。然而,从长远来看,它们可能会变得具有成本效益,特别是在回归测试中反复使用时。测试自动化的频繁候选者BI报告测试商业、政府合规数据聚合处理数据清理和归档数据质量测试数据对账(例如,从源到目标)数据转换尺寸表数据加载端到端测试ETL,ELT验证和验证测试事实表数据加载文件/数据加载验证增量负载测试负载和可扩展性测试缺少文件、记录、字段性能测试引用完整性回归测试安全测试源数据测试和分析分期,ODS数据验证单元、集成和回归测试由于处理的复杂性以及应验证的源和目标的数量,这些测试的自动化可能是必要的。对于大多数项目,数据管道测试过程旨在验证和实施数据质量。今天可用的各种数据类型带来了测试挑战今天有各种各样的数据类型,从文本、数字和日期等传统结构化数据类型到音频、图像和视频等非结构化数据类型。此外,各种类型的半结构化数据,如XML和JSON,被广泛用于Web开发和数据交换。随着物联网(IoT)的出现,各种数据类型激增,包括传感器数据、位置数据和机器对机器通信数据。随着这些数据类型的提取和转换,如果没有适当的工具,测试可能会变得更加复杂。这导致了新的数据管理技术和分析技术,如流处理、边缘

    02

    linux系统编程(3)

    一 线程间同步 同步:相互之间配合完成一件事情 互斥:保证访问共享资源的完整性(有你没我) POSIX 线程中同步:使用信号量实现 信号量 : 表示一类资源,它的值表示资源的个数 对资源访问: p操作(申请资源) [将资源的值 - 1] .... V操作(释放资源) [将资源的值 + 1] 1.定义信号量 sem_t  sem ; 2.初始化信号量 int sem_init(sem_t *sem, int pshared, unsigned int value); 参数: @sem         信号量 @pshared     0:线程间使用 @value       初始化的信号量的值 返回值: 成功返回0,失败返回-1 3.P操作 int sem_wait(sem_t *sem); 4.V操作 int sem_post(sem_t *sem); 二 进程间通信(进程间数据交互) (1)传统进程间通信方式   [1]无名管道   [2]有名管道   [3]信号 (2)System 5 IPC对象进程间通信方式   [1]消息队列   [2]共享内存   [3]信号灯集 (3)socket通信 (4)Android系统中增加Binder进程间通信方式 Linux 支持以上所有进程间通信方式 三 管道进程间通信 (1)无名管道 特点: 只能用于具有亲缘关系进程间通信(具有亲缘关系的进程具有数据拷贝动作(复制父进程创建子进程)) int pipe(int pipefd[2]); 功能:创建一个无名管道 参数: @pipefd  获取操作无名管道的文件描述符  pipefd[0]:读无名管道 pipefd[1]:写无名管道 返回值: 成功返回0,失败返回-1 (2)管道读写规则  读端存在  ,写管道 ---->只要管道没有满,都可以写入数据到管道 读端不存在,写管道 ---->此时写管道没有意义,操作系统会发送SIGPIPE杀死写管道的进程 写端存在,  读管道 ---->此时管道中读取数据,管道中没有数据,读阻塞 写端不存在,读管道 ---->此时管道中读取数据,管道中没有数据,此时不阻塞,立即返回,返回值0 (3)有名管道 特点:可以用于任意进程间通信,它是一种特殊的文件,在文件系统存在名字,      而文件中存放的数据是在内核空间,而不是在磁盘上 1.创建一个有名管道文件 int mkfifo(const char *pathname, mode_t mode); @pathname  有名管道存在的路径 @mode      有名管道的权限 返回值: 成功返回0,失败返回-1 2.打开有名管道文件 open 如果有名管道的一端以只读的方式打开,会阻塞,直到另一端以写(只写或读写)的方式打开 如果有名管道的一端以只写的方式打开,会阻塞,直到另一端以读(只读或读写)的方式打开 3.读写操作  read /write 4.关闭管道文件 close(fd); 四 信号 信号是异步进程间通信方式 进程对信号的响应方式: <1>忽略   SIGKILL 和 SIGSTOP 不能忽略 <2>捕捉   当进程收到信号,此时执行的信号处理函数  <3>默认   大部分信号对进程的默认操作方式都是杀死进程   子进程状态发生改变的时候,操作系统向父进程发送SIGCHLD,默认对它处理方式是忽略 typedef  void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler); 功能:设置进程对信号处理方式 参数: @signum  信号的编号 @handler  SIG_IGN : 忽略信号  SIG_DFL : 使用默认处理方式  函数名  : 捕捉方式处理 返回值: 成功返回handler,失败返回SIG_ERR 练习: 如何进行不阻塞,不轮训方式回收僵尸态子进程 2.在进程中设置一个定时器 unsigned int alarm(unsigned int seconds); 参数: @seconds 定时的时间,以秒为单位 注意: 一旦定时时间完成,操作系统就会向进程发送SIGALRM信号 A进程: 读文件,写管道 A进程结束条件:文件没有数据可读 B进程: 读管道,写文件 B进程结束条件:在

    02
    领券