UNIX环境变量--IPC之管道通信

管道通信使用先入先出的原则进行读写,且不能是lseek函数定位读写位置。关注微信公众号,码客资源网

一、无名管道

  无名管道是一种特殊类型的文件,完全由操作系统管理和维护,因为其存储位置只有亲缘关系的进程知道,所以只能用于亲缘关系的进程之间通信,而且,其内核资源会在两个通信进程退出后自动释放,无名管道创建函数为:

//from /usr/include/unistd.h
int pipe(int fd[2]);

函数pipe()返回两个文件描述符,其中fd[0]用来完成读操作,fd[1]完成写操作,默认阻塞方式。

以阻塞方式读管道时:
(1)有读进程,无写进程:

  1. 管道内无数据时,立即返回
  2. 管道内数据不足,读出所有数据
  3. 管道内数据充足,读出期望数据

(2)有读进程,有写进程:

  • 管道内无数据时,读进程阻塞
  • 管道内数据不足,读出所有数据
  • 管道内数据充足,读出期望数据

以阻塞方式写管道时:
(1)有写进程,无读进程:

  • 写进程将收到SIGPIPE信号,wirte函数返回-1

(2)有写进程,有读进程,且管道内有写空间:

  • 写入成功

另外可以使用fcntl()函数使用O_NDELAY或O_NONBLOCK属性,设置管道为非阻塞模式。

 

#include <stdio.h>
FILE * popen(const char *command , const char *type );
int pclose(FILE *stream);

作用:

    popen函数允许一个程序将另外一个程序作为新进程来启动,并可以传递数据或者通过它接受数据。

    其内部实现为调用 fork 产生一个子进程,执行一个 shell, 以运行命令来开启一个进程,这个进程必须由 pclose() 函数关闭

参数说明:

  command: 是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用 -c 标志,shell 将执行这个命令。

       type : 只能是读或者写中的一种。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入。。

缺点:

    使用popen的不好影响是,针对每个popen调用,不仅要启动一个被请求的程序,还要启动一个shell,即每个popen调用将多启动两个进程。

实例:

#include<stdio.h> 
#include<unistd.h> 
#include<string.h>   
int main() 
{ 
    FILE *fp=NULL; 
    FILE *fh=NULL; 
    char buff[128]={0};   
    memset(buff,0,sizeof(buff)); 
    fp=popen("ls -l","r");//将命令ls-l 通过管道读到fp 
    fh=fopen("shell.c","w+");// 创建一个可写的文件 
    fread(buff,1,127,fp);//将fp的数据流读到buff中 
    fwrite(buff,1,127,fh);//将buff的数据写入fh指向的文件中   
    pclose(fp); 
    fclose(fh);   
    return 0;   
} 

 运行结果:

[lol@localhost practice]$ ls
popen popen.c shell.c
[lol@localhost practice]$ cat shell.c
total 12
-rwxrwxr-x. 1 lol lol 5478 May 24 15:39 popen
-rw-rw-r--. 1 lol lol 473 May 24 15:39 popen.c
-rw-rw-r--. 1 lol lol  [lol@localhost practice]$ vim popen.c
[lol@localhost practice]$

二、有名管道

有名管道可以通过mknod 命令创建,也可以使用函数mkfifo()创建,可以使用在系统中任意两个进程之间进行通信,且创建的管道文件存储在硬盘上,不会随着进程结束而消失。mknod使用如下:

root@wangmumu-virtual-machine:/home/wangmumu/桌面/shares/FIFO# mknod fifo p
root@wangmumu-virtual-machine:/home/wangmumu/桌面/shares/FIFO# ls -l
总用量 24
prw-r--r-- 1 root   root       0  8月 26 00:30 fifo
-rwxr--r-- 1 nobody nogroup  872  8月 25 23:57 fifo_read.c
-rwxr--r-- 1 nobody nogroup  884  8月 25 23:52 fifo_write.c
-rwxr-xr-x 1 root   root    7613  8月 25 23:57 read
-rwxr-xr-x 1 root   root    7651  8月 25 23:52 write

mkfifo()函数声明如下:

// from /usr/include/sys/stat.h
int mkfifo(char* path,mode_t mode);

函数的第一个参数为有名管道文件,函数调用时,必须不存在,执行成功返回0,失败返回-1。
(1)如果没有指定O_NONBLOCK方式打开时(默认情况),当进程以写或读的方式打开管道文件,必须有另一个进程以相对应的读或写方式也打开该文件,否则该进程将阻塞在open()位置。

(2)如果指定O_NONBLOCK方式打开,则只读open将立即返回0,但是如果目前没有读进程打开,而直接以写方式打开文件,则open将返回-1,并将errno置为ENXIO,所以建议一般先以读方式打开有名管道。
(3)若两个进程都已打开,但中途某进程退出,则:

    读进程退出,返回SIGPIPE信号
    写进程退出,读进程将不再阻塞,直接返回 0
 

示例:

以下为有名管道代码实现,写进程不断获取终端输入,并写到有名管道上,读进程阻塞读取管道中数据,并将数据打印出来。

写进程代码实现:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> 
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "fifo"
int main()
{
    int fd = 0;
    int ret = 0;
    char buffer[1024] = {0};

    if(access(FIFO_NAME,F_OK) == -1)
    {
        ret = mkfifo(FIFO_NAME,0755);
        if(ret != 0)
        {
            printf("mkfifo err!\n");
            return -1;
        }
    }

    printf("mkfifo success,open O_WRONLY!\n");

    fd = open(FIFO_NAME,O_WRONLY);
    if(fd < 0)
    {
        printf("open FIFO_NAME fail!\n");
        return -1;
    }
    else
    {
        while(1)
        {
            gets(buffer);
            //strcpy(buffer,"hello nihao\n");
            ret = write(fd,buffer,strlen(buffer));
            if(-1 == ret )
            {
                printf("write buffer fail!\n");
                return -1;
            }
            memset(buffer,0,sizeof(buffer));
            sleep(1);
        }

    }

    close(fd);
    return 0;
}

读进程代码实现:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h> 
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#define FIFO_NAME "fifo"
int main()
{
    int fd = 0;
    int ret = 0;
    char buffer[1024] = {0};

    unlink(FIFO_NAME);
    ret = mkfifo(FIFO_NAME,0755);
    if(ret != 0)
    {
        printf("mkfifo err!\n");
        return -1;
    }


    printf("mkfifo success,open O_RDONLY!\n");

    fd = open(FIFO_NAME,O_RDONLY);
    printf("zusissiiii\n");
    if(fd < 0)
    {
        printf("open FIFO_NAME fail!\n");
        return -1;
    }
    else
    {
        while(1)
        {
            ret = read(fd,buffer,sizeof(buffer));
            if(-1 == ret )
            {
                printf("write buffer fail!\n");
                return -1;
            }
            printf("FIFO read buffer:%s\n",buffer);
            memset(buffer,0,sizeof(buffer));
            sleep(1);
        }

    }

    close(fd);
    return 0;
}

【电力系统】单机无穷大电力系统短路故障暂态稳定Simulink仿真(带说明文档)内容概要:本文档围绕“单机无穷大电力系统短路故障暂态稳定Simulink仿真”展开,提供了完整的仿真模型与说明文档,重点研究电力系统在发生短路故障后的暂态稳定性问题。通过Simulink搭建单机无穷大系统模型,模拟不同类型的短路故障(如三相短路),分析系统在故障期间及切除后的动态响应,包括发电机转子角度、转速、电压和功率等关键参数的变化,进而评估系统的暂态稳定能力。该仿真有助于理解电力系统稳定性机理,掌握暂态过程分析方法。; 适合人群:电气工程及相关专业的本科生、研究生,以及从事电力系统分析、运行与控制工作的科研人员和工程师。; 使用场景及目标:①学习电力系统暂态稳定的基本概念与分析方法;②掌握利用Simulink进行电力系统建模与仿真的技能;③研究短路故障对系统稳定性的影响及提高稳定性的措施(如故障清除时间优化);④辅助课程设计、毕业设计或科研项目中的系统仿真验证。; 阅读建议:建议结合电力系统稳定性理论知识进行学习,先理解仿真模型各模块的功能与参数设置,再运行仿真并仔细分析输出结果,尝试改变故障类型或系统参数以观察其对稳定性的影响,从而深化对暂态稳定问题的理解。
本研究聚焦于运用MATLAB平台,将支持向量机(SVM)应用于数据预测任务,并引入粒子群优化(PSO)算法对模型的关键参数进行自动调优。该研究属于机器学习领域的典型实践,其核心在于利用SVM构建分类模型,同时借助PSO的全局搜索能力,高效确定SVM的最优超参数配置,从而显著增强模型的整体预测效能。 支持向量机作为一种经典的监督学习方法,其基本原理是通过在高维特征空间中构造一个具有最大间隔的决策边界,以实现对样本数据的分类或回归分析。该算法擅长处理小规模样本集、非线性关系以及高维度特征识别问题,其有效性源于通过核函数将原始数据映射至更高维的空间,使得原本复杂的分类问题变得线性可分。 粒子群优化算法是一种模拟鸟群社会行为的群体智能优化技术。在该算法框架下,每个潜在解被视作一个“粒子”,粒子群在解空间中协同搜索,通过不断迭代更新自身速度与位置,并参考个体历史最优解和群体全局最优解的信息,逐步逼近问题的最优解。在本应用中,PSO被专门用于搜寻SVM中影响模型性能的两个关键参数——正则化参数C与核函数参数γ的最优组合。 项目所提供的实现代码涵盖了从数据加载、预处理(如标准化处理)、基础SVM模型构建到PSO优化流程的完整步骤。优化过程会针对不同的核函数(例如线性核、多项式核及径向基函数核等)进行参数寻优,并系统评估优化前后模型性能的差异。性能对比通常基于准确率、精确率、召回率及F1分数等多项分类指标展开,从而定量验证PSO算法在提升SVM模型分类能力方面的实际效果。 本研究通过一个具体的MATLAB实现案例,旨在演示如何将全局优化算法与机器学习模型相结合,以解决模型参数选择这一关键问题。通过此实践,研究者不仅能够深入理解SVM的工作原理,还能掌握利用智能优化技术提升模型泛化性能的有效方法,这对于机器学习在实际问题中的应用具有重要的参考价值。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chiang木

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值