day09

来源:互联网 发布:男士护肤 知乎 旁氏 编辑:程序博客网 时间:2024/05/16 05:30
回忆上周内容:
一、进程的退出
exit(3)、_exit(2)、atexit(3)、on_exit(3)
二、进程资源的回收
wait(2)、waitpid(2)
孤儿进程、僵尸进程
三、加载新的映像
四、使用system调用linux命令
/bin/sh -c command

今天的内容:
一、使用C程序访问环境变量
1、系统提供了一个全局变量。extern char **environ;
使用全局变量environ将所有的环境变量输出。代码参见 myenv.c

2、int main(int argc,const char *argv[],char *envp[])
举例验证,代码参见myenv1.c
int main(void)
3、操作环境变量的函数
getenv(3)
#include <stdlib.h>
char *getenv(const char *name);
功能:获取环境变量的值
参数:
name:环境变量的名字
返回值:
NULL  没有找到这个环境变量
返回环境变量的值的首地址。

putenv(3)
#include <stdlib.h>
int putenv(char *string);
功能:改变一个环境变量的值,或者增加一个环境变量
参数:
string:name=value
返回值:
0   成功
非0  错误
clearenv(3)
#include <stdlib.h>
int clearenv(void);
功能:清除环境变量
参数:
void
返回值:
0   成功
非0  失败

setenv(3)
#include <stdlib.h>
int setenv(const char *name,const char *value,int         overwrite);
功能:改变或增加一个环境变量
参数:
name:指定了环境变量的名字
value:指定了环境变量的值
overwrite:
0  环境变量存在,那么值不改变。
非0  环境变量存在,值被替换。

返回值:
0  成功
-1 失败 errno被设置

int unsetenv(const char *name);
功能:删除环境变量
参数:
name:指定环境变量的名字
返回值:
0  成功
-1 失败 errno被设置

环境变量函数测试  代码参见env_test.c

二、文件输入重定向
举例说明   代码参见upper.c  wrap.c
三、管道
管道分为两种:有名管道、无名管道
无名管道的创建使用pipe(2)
#include <unistd.h>
int pipe(int pipefd[2]);
功能:创建管道
参数:
pipefd[2]:管道的两个文件描述符。
pipefd[0]  读端
pipefd[1]  写端
返回值:
0  成功
-1 错误  errno被设置
举例验证管道的使用  代码参见pipe.c

1、父进程创建管道
2、fork(2)创建子进程
3、父进程关闭写端,子进程关闭读端
4、子进程写,父进程读
无名管道中需要使用到文件描述符,所以,无名管道应用于具有亲缘关系的进程间通信。

有名管道:
实质是创建一个管道文件,一个进程向文件写数据,一个从文件中读数据。
创建有名管道需要使用mkfifo(3)
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
功能:创建一个有名的管道文件
参数:
pathname:指定管道文件的名字
mode:指定了管道文件的权限
返回值:
0  成功
-1 错误  errno被设置

举例验证有名管道的进程间通讯。
代码参见    channelA.c  channelB.c

补充:
带环境变量的加载映像。代码参见  execle.c

python  perl  bash
 
homework:
自己编写程序实现mysh。内部命令和外部命令的区别

四、信号
什么是信号?
信号就是软中断.
什么是软中断?
软中断就是软件模拟的中断。
什么是中断?
中断服务程序。

信号是进程的异步通讯机制。
系统提供的信号。如何察看?
kill -l

一般来说,信号有64个信号。
kill  -信号编号  pid

信号的产生、信号阻塞、信号未决、进程对信号的捕获、信号处理程序

进程对信号的默认处理动作就是终止当前进程。
用户可以根据自己的需求来设置进程对信号的处理。
SIG_DFL    缺省的
SIG_IGN    忽略
用户自定义信号处理函数

需要向进程注册一个函数,当信号到来的时候,使用这个注册的信号处理函数来处理信号到达。
signal(2)
#include <signal.h>
typedef void (*sighandler_t)(int);

sighandler_t  signal(int signum, sighandler_t handler);
功能:为信号注册信号处理函数
参数:
signum:信号的名字或者信号编号
handler:
SIG_DFL   默认
SIG_IGN   忽略
用户自定义的信号处理函数
返回值:
SIG_ERR   错误
返回原来的信号处理函数
举例验证,使用signal函数为进程注册信号处理函数。
代码参见   signal.c

信号的产生:
1、硬件产生信号
ctrl+c   ctrl+\
2、使用linux命令发送信号
kill  -信号编号  pid
3、使用函数给进程发送信号
kill(2)
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
功能:发送信号给一个进程
参数:
pid: 正数  进程的pid  给这个进程发送信号
sig: 指定信号编号
返回值:
0   成功
-1   错误   errno被设置

举例验证 kill(2)的使用  代码参见mykill.c

raise(3)
#include <signal.h>
int raise(int sig);
功能:给当前进程发送信号
参数:
sig:要发送的信号编号
返回值:
0  成功
非0 失败

举例验证   使用raise(3)给自己发送信号
代码参见raise.c

alarm(2)
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
功能:设置一个传递信号的闹钟
参数:
seconds:  设置闹钟的秒数
返回值:
保留的秒数

举例验证 alarm(2)的使用
代码参见   myalarm.c

总结:
一、环境变量
二、文件输入重定向
三、管道(无名管道、有名管道)
四、信号基础
homework:
自己编写程序实现mysh。内部命令和外部命令的区别