1.进程对环境变量的操作
在Linux中,你可以使用以下几个函数来操作环境变量:
getenv
: 获取环境变量值。setenv
: 设置或修改环境变量值。unsetenv
: 删除环境变量getenv:
- 参数:接受一个字符串作为参数,表示要获取的环境变量的名称。
- 用法:调用
getenv
函数时,传入要获取的环境变量的名称,函数返回对应环境变量的值的字符串指针。如果环境变量不存在,则返回 NULL。setenv:
- 参数:
- 第一个参数是要设置或修改的环境变量的名称。
- 第二个参数是要设置的环境变量的值,是一个字符串。
- 第三个参数是一个整数,表示是否覆盖已存在的同名环境变量的值。
- 如果第三个参数为 0,则不覆盖已存在的同名环境变量。
- 如果第三个参数为非零值,则覆盖已存在的同名环境变量。
- 用法:调用
setenv
函数时,传入要设置或修改的环境变量的名称、要设置的环境变量的值以及是否覆盖已存在的同名环境变量的值的选项。如果设置或修改成功,则返回 0;否则返回 -1,并设置 errno。unsetenv:
- 参数:接受一个字符串作为参数,表示要删除的环境变量的名称。
- 用法:调用
unsetenv
函数时,传入要删除的环境变量的名称,函数会删除该环境变量。如果成功删除,则返回 0;否则返回 -1,并设置 errno。
#include <stdio.h>
#include <stdlib.h>
int main(void) {// 利用getenv获取环境变量char* path = getenv("PATH");printf("Original PATH: %s\n", path);// 利用setenv设置环境变量setenv("TEST_ENV", "123456", 1);printf("TEST_ENV: %s\n", getenv("TEST_ENV"));// 修改现有的环境变量setenv("PATH", "/usr/local/bin", 1);printf("New PATH: %s\n", getenv("PATH"));// 利用unsetenv删除环境变量unsetenv("TEST_ENV");printf("After unset, TEST_ENV: %s\n", getenv("TEST_ENV"));return 0;
}
在这个程序中,我们首先使用
getenv
函数来获取 PATH 环境变量的当前值。然后我们使用setenv
函数来创建一个新的环境变量 TEST_ENV 并为它设置一个值。接下来,我们再一次使用setenv
函数来修改 PATH 环境变量的值。最后,我们使用unsetenv
函数来删除我们之前创建的 TEST_ENV 环境变量。我们可以看到,通过调用getenv
函数,TEST_ENV 环境变量在被删除之后,返回的值为 NULL。
2.进程间通信
管道是进程间通讯的一种实现
2.1无名管道
父进程的任务:
#include<t_stdio.h> #include<t_file.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include <sys/types.h> #include <sys/wait.h> //进程间通信int main(){char buf[128];char * msg="this is a test..\n";int fd[2];//创建管道int pp =pipe(fd);if(pp==-1)E_MSG("pipe",-1); //创建子进程pid_t pid = fork();if(pid==-1)E_MSG("fork",-1);if(pid==0){//子进程close(fd[1]);//关闭写端//读取数据,如果管道没有数据,就阻塞等待int r = read(fd[0],buf,128);write(1,buf,r);//将buf输出到屏幕//关闭读端close(fd[0]);exit(0);}else {//父进程close(fd[0]);write(fd[1],msg,strlen(msg));close(fd[1]);wait(NULL);//阻塞等待子进程结束}return 0; }
具体代码如上,我们首先创建无名管道,然后才能创建子进程,然后分别在父进程进行写入操作,记得关闭读操作,然后在子进程继续读操作,关闭写操作,具体操作如上
2.2有名管道
有名管道(Named Pipe),也被称为FIFO(First In, First Out),是一种特殊类型的管道,与普通管道不同之处在于它有一个在文件系统中可见的路径名,这使得它可以在不相关的进程之间进行通信。有名管道提供了一种进程间通信的方式,允许不相关的进程通过读写同一个管道来进行数据交换。
在Unix/Linux系统中,有名管道通过mkfifo函数来创建。mkfifo函数创建一个新的FIFO文件,如果该文件已经存在,则不进行任何操作。mkfifo的原型如下:
#include <sys/types.h> #include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);
参数说明:
pathname
:指定要创建的FIFO的路径名。mode
:指定FIFO的权限。通常使用八进制数表示,比如0666
表示允许所有用户读写。
这里 我们创建三个文件来创建一个有名管道文件来进行读和写操作,来模拟不同进程之间的通信:
这是创建有名管道的函数:
#include<t_stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char * argv[]){//创建有名管道类型文件int ff = mkfifo(argv[1],0644);if(ff==-1)E_MSG("mkfifo",-1);printf("file ...%s success create\n",argv[1]);return 0;
}
这是向有名管道写入数据的函数:
#include<t_stdio.h>
#include<t_stdio.h>
#include <asm-generic/fcntl.h>
#include<string.h>
int main(int argc, char * argv[]){char * msg="this is a test..\n";//打开文件,以写的方式打开int fd = open(argv[1],O_WRONLY);if(fd==-1)E_MSG("open",-1);write(fd,msg,strlen(msg));close(fd);return 0;
}
这是向管道读数据的函数:
#include<t_stdio.h>
#include<t_stdio.h>
#include <asm-generic/fcntl.h>
#include<string.h>int main(int argc, char * argv[]){char buf[128];//打开文件,以写的方式打开int fd = open(argv[1],O_RDONLY);if(fd==-1)E_MSG("open",-1);int r= read(fd,buf,128);write(1,buf,r);close(fd);return 0;
}
写入和读数据必须在两个进程同时进行:
当在进程1中向管道写入数据时,会堵塞(这时管道文件数据为0),必须在另外一个进程2中读入数据,这样管到2就会输出“this is a test"。