标签:comm 没有 center 抽象 交互 getenv lag 读取 memset
异常处理
异常的类别
1.中断
2.陷阱
3.故障
4.终止
Linux/A32系统中的异常
进程
获取进程ID
每个进程有一个唯一的非零正数进程ID(PID)。
pid_t getpid(void); /*返回调用进程的PID*/
pid_t getppid(void); /*返回它的父进程的PID*/
创建和终止进程
进程总是处于以下三种状态之一:
终止。进程永远停止。进程终止的原因:1)收到一个信号,默认行为是终止程序2)从主程序返回3)
调用exit函数。
void exit(int ststus)
pid_t fork(void); /*子进程返回0,父进程返回子进程的pid,出错则返回-1。*/
共享文件,子进程继承了父进程所有打开的文件。
回收子进程
pid_t waitpid(pid_t pid,int *status,int options);
修改默认行为:可以通过将options设置为常量,修改默认行为。
检查已回收子进程的退出状态:如果status参数是非空的,则status参数会放上关于导致返回的子进程的状态信息。
pid_t wait(int *status);
让进程休眠
unsigned int sleep(unsigned int secs); /*返回还要休眠的秒数*/
int pause(void); /*总是返回-1*/
加载并运行程序
execve函数在当前进程的上下文中加载并运行一个新程序。
int execve(const char*filename,const char *argv[],const char *envp);
/*成功则不返回,错误返回-1*/
利用fork和execve运行程序
信号术语
发送信号
pid_t getpgrp(void);
int setpgrp(pid_t pid,pid_t pgid);
int kill(pid_t pid,int sig);
unsigned int alarm(unsigned int secs); /*返回前一次闹钟剩余的秒数,若没有则返回0*/
接收信号
信号处理问题
不可以用信号来对其他进程中发生的事件计数。
可移植的信号处理
int sigaction(int signum,struct sigaction *act,struct sigaction *oldact);
显示地阻塞和取消阻塞信号
int sigprocmask(int how,const sigset_t *set,sigset_t *oldset);
同步流以避免并发错误
setjmp函数在env缓冲区中保存当前调用环境,供后面longjmp使用,并返回0。调用环境包括程序计数器、栈指针和通用目的寄存器。
int setjmp(jmp_buf env);
int sigsetjmp(setjmp_buf env,int savesigs);
longjmp函数从env缓冲区中恢复调用环境,然后触发一个从最近一次初始化env的setjmp调用的返回。然后setjmp返回,并带有非零的返回值retval。
void longjmp(jmp_buf env,int retval);
void siglongjmp(sigjmp_buf env,int retval);
exec1.c代码运行如下
execvp()
会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件
setenv函数是修改或添加环境变量的函数
1.如果name在环境中不存在,那么很好办,在环境中添加这个新的变量就OK。
setenv函数必须在environment list中增加一个新的entry,然后动态申请存储空间来存储name=value,并且使entry指向该空间。
2.如果在环境中name已经存在,那么
(a)若overwrite非0,那么更新name的value(实质是更新环境表,指向新的value)
(b)若overwrite为0,则环境变量name不变,并且也不出错
setenv函数不必在environment list中增加一个新的entry。当overwrite为0, 则不必改动entry的指向;当overwrite非0, 则直接使该entry指向name=value,当然该name=value也是存储在动态申请的内存里。
environvar.c代码简单打印环境变量表,运行结果如下
每个程序都有一个环境表,它是一个字符指针数组,其中每个指针包含一个以NULL结尾的C字符串的地址。全局变量environ则包含了该指针数组的地址
consumer.c代码中:
memset(void *s,int ch,size_t n);将s中前n个字节用ch替换并返回s
open(const char *pathname,int flags);第一个参数是欲打开的文件路径字符串,第二个参数是打开方式
consumer.c代码运行如下
testmf.c代码中调用了mkfifo函数
mkfifo(FIFO_NAME, 0777);//依据FIFO_NAME创建fifo文件,0777依次是相应权限mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取
listargs.c 代码运行结果如下,证明了shell并不将重定向标记和文件名传递给程序
pipedemo.c展示了如何创建管道并使用管道来向自己发送数据
pipedemo2.c说明了如何将pipe和fork结合起来,创建一对通过管道来通信的进程。在程序中显示了从键盘到进程,从进程到管道,再从管道到进程以及从进程回到终端的数据传输流
sigactdemo.c中sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号
int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);
sigactdemo.c执行如下
SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号
代码链接:https://git.oschina.net/929210354/Linux
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 100/100 | 1/2 | 20/20 | |
第二周 | 92/192 | 1/3 | 18/38 | |
第三周 | 195/387 | 1/4 | 22/60 | |
第四周 | 180/567 | 0/4 | 30/90 | |
第五周 | 120/687 | 1/5 | 20/20 | |
第六周 | 130/817 | 1/6 | 18/38 | |
第七周 | 550/1367 | 1/7 | 22/60 | |
第八周 | 0/1367 | 2/9 | 30/90 | |
第九周 | 60/1427 | 2/11 | 20/20 | |
第十周 | 514/1941 | 2/13 | 18/38 | |
第十一周 | 1856/3797 | 2/15 | 22/60 |
标签:comm 没有 center 抽象 交互 getenv lag 读取 memset
原文地址:http://www.cnblogs.com/dwc929210354/p/6107182.html