目录
在Linux/Unix系统中,进程间通信方式(Inter-Process Comunication)通常有如下若干中方式:
1、文件和记录锁定
2、管道
3、信号
4、system-V
5、POSIX信号量
6、套接字 socket
这些通信机制统称IPC,它们各有特色,各有适用的场合。
首先介绍
几个系统关键api
exec函数族
在进程中加载新的程序文件或脚本,覆盖原有代码重新运行
函数原型和如何调用如图所示
参考文献:
Linux进程------exec族函数、exec族函数与fork函数的配合_exec函数 代替 fork-CSDN博客
这个函数网上的介绍有很多写的非常好的,就不过多赘述了
getenv()
首先介绍如何查看Linux系统环境变量
可输入env或者export查看,如图:
这是我的系统环境变量
获取系统环境变量函数
char *getenv(const char *name)
搜索 name 所指向的环境字符串,并返回相关的值给字符串。
包含在头文件#include <stdlib.h>中
具体用法为:
cpp
p = getenv("USER")
printf("USER=%s\n", p);// 获取当前用户名
p = getenv("PWD")
printf("PWD=%s\n", p);//获取当前路径
p = getenv("PATH")
printf("PATH=%s\n", p);//获取PATH环境变量
system()
函数原型:
#include <stdlib.h>
int system(const char *command);
用法:在system()中直接添加想要调用的命令如system("ls -l");直接执行即可
重点:
system和fopen的区别
system函数的大概原理:
mysytem.c
cpp
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int mysystem(char *cmd)
{
char tmp_cmd[1024] = {0};
strcpy(tmp_cmd, cmd); //将命令拷贝到临时的字符数组中
// 参数列表
char *argv[100] = {0};
int argc = 0;
//函数原型:
//#include <string.h>
//char *strtok(char *str, const char *delim)
//str -- 要被分解成一组小字符串的字符串。
//delim -- 包含分隔符的 C 字符串。
//该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针
char *p = strtok(tmp_cmd, " ");
argv[argc++] = p;
while (1)
{
/* strtok函数中有两个指针
第一次调用这个函数是在while循环体之外,字符串中匹匹配的"delim"
在第一个字符串和第二个字符串之间
数此时的返回值第一个指针指向已经分割的字符串,
第二个函数内部的指针指向返回值的指针+1,
所以循环内的函数的第一个参数要填NULL是为了保留函数指针此时所在的位置以便于继续执行 */
p = strtok(NULL, " ");
if (p == NULL)
{
printf("参数解析完毕\n");
break;
}
argv[argc++] = p;
}
// 检查参数是否切割完毕
for (int i = 0; i < argc; i++)
{
printf("%s\t", argv[i]);
}
printf("\n");
// 创建一个子进程
pid_t pid = fork();
if (pid == 0) // 子进程
{
// 执行程序,路径视为环境变量
//带p的一类exac函数,包括execlp、execvp、execvpe,如果参数file中包含'/',
//则就将其视为路径名,否则就按 PATH环境变量,
//在它所指定的各目录中搜寻可执行文件。
if (execvp(argv[0], argv) < 0)
{
perror("加载程序失败\n");
return -1;
}
return 0; // 退出子进程
}
// 父进程 ,等待回收子进程的资源
wait(NULL);
return 1;
};
int main()
{
mysystem("ls -l");
}
可以看到,在Linux内核中,system和popen的实现原理差不多,都是先fork一个进程,然后execv环境变量,然后return,system和popen的区别在于popen需要搭配pclose使用,因为popen在执行完之后没有释放资源,需要手动去回收资源,要不然就会变成僵尸进程。
参考文献:
Linux的system()和popen()差异_linux system 和 popen-CSDN博客
文件和记录锁定通信
一种非常古老原始的通信方式,在Linux中磁盘中创建一个文本文件,进程可以通过读写同一个文件来交换信息,已经给淘汰了,这里简单介绍一下
cpp
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
// 全局变量
char value[1024] = {0};
int main()
{
// 创建一个文件
int fd = open("test.txt", O_RDWR | O_CREAT | O_EXCL, 0777);
// 创建一个进程
pid_t pid = fork();
if (pid == 0) // 子进程获取数据
{
while (1)
{
printf("子进程,请输入数据\n");
scanf("%s", value);
// 写入文件
lseek(fd, 0, SEEK_SET);
write(fd, value, strlen(value));
}
}
if (pid > 0) // 父进程输出数据
{
while (1)
{
// 读取文件
lseek(fd, 0, SEEK_SET);
read(fd, value, 1024);
printf("输出数据%s\n", value);
sleep(3);
}
}
}
欲知后事如何,且听下回分解,下一篇,更精彩