ls -l >test.txt
chmod u+s main
echo $USER
int getuid() 得到实际用户(uid_t)
int geteuid() 得到有效用户(uid_t)
目录:
chdir 切换目录
mkdir 创建目录
rmdir 删除目录
unlink 删除文件
umassk 设置文件权限屏蔽位
stat 文件目录状态
fstat
目录遍历:
opendir man 3 opendir
readdir man 3 readdir
opendir
readdir man 2 readdir
scandir
seekdir
closedir
如果错误发生,一般返回NULL 或者 0
int scandir(const char *drip,//目录名
struct dirent ***namelist,//返回目录列表
int (*filter)(const struct dirent *),//回调函数,过滤目录 NULL 表示不过滤
int (*compar)(const struct dirent **,const struct dirent **)//排序返回目录, NULL 不排序
);
进程:
ps au
ps aue
ps a
top
pstree
向进程发送信号
kill -s 信号 进程id
kill -l 显示进程能接收的所有信号
system可以调用shell命令
int system(const char * command);
popen
FILE *popen(const char * command, const char *type);
int pclose(FILE *STREAM);
int fileno(FILE *stream);
函数fileno检测stream函数,返回它的整数形式的文件描述符。
替换当前进程的代码空间中的代码数据
函数本身不创建新的进程
exec execl
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
第一个参数:替换的程序
第二个参数...:命令行
命令行格式:命令名 选项参数
命令行结尾必须是空字符串
不创建新的进程
替换当前进程的代码
excel 搜索绝对路径
excelp 搜索相对路径
fork
1.创建进程
1.1int pid = fork();
1.2.新进程的代码是什么:克隆父进程的代码,且克隆了执行位置。父进程执行过的代码将不会执行
1.3.在子进程不调用fork语句所以返回值为0
1.4.父子进行同时进行
使用fork实现多任务
进程
线程
信号
异步
线程池
进程池
2.理解进程
2.1父子进程的关系
两个独立的进程
互为父子的关系 子进程节点树挂在父进程下
2.2问题:
2.2.1.父进程先结束
子进程就依托根进程init:孤儿进程
孤儿进程没有任何问题,没有任何的危害.
2.2.2.子进程先结束
子进程会成为僵尸进程
僵尸进程不占用内存,不占用CPU,但在进程任务管理树上占用一个节点
僵尸进程造成进程名额资源浪费
所以要处理僵尸进程
2.2.3.僵尸进程使用wait回收
#include <unistd.h>
void _exit(int status);
#include <stdlib.h>
void _Exit(int status);
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
2.2.4父进程怎么知道子进程退出?
子进程结束通常会想父进程发送一个信号
SIGCHLD
[alexliu@localhost day05]$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
2.2.5父进程会子进程退出信号
int signal(int sig,void(*fun)(int));
向系统注册:只要sig信号发送,系统停止进程,并调用fun函数
当函数执行完毕,继续原来的程序
2.2.5.1实现处理函数
2.2.5.2使用signal绑定信号与函数
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
2.2.6.2文件资源
说明:子进程克隆整个内存区域
但内存区域指向不同的物理空间
尽管克隆,但内存独立,不能互相访问
多进程实现多任务,进程之间的数据交换是大问题
inter process communication (IPC)
映射内存:
MAP_SHARED:映射到同一物理内存
MAP_PRIVATE:映射到不同的物理内存
int *a = mmap(0,4,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED,0,0);//父子进程可以访问*a
int *a = mmap(0,4,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,0,0);//父子进程不可以访问*a
int *a = sbrk(4);//私有的父子进程不可以访问*a
两个进程之间,文件描述符质量的是同一个文件内核号
结论:
进程的数据交换,基于两种方式:
共享内存:有序内存(管道,socket)、无序内存(mmap)
文件:有序文件、无序文件(普通文件)
基于内核对象:文件,内存,队列
回顾:
1、目录遍历
2、进程创建system popen exec fork
3、僵尸进程出现的条件及回收
4、利用多进程实现简单的任务
5、理解进程的克隆
作业:
1、使用两个进程,查找素数
A进程查找1-5000
B进程查找2001-10000
把素数写入文件
2、写一个多任务程序(两个进程数据共享)
A进程查找素数,放入mmap分配的空间
B进程把mmap的数据取出来,判定两个数据是否相邻,如果相邻则打印这两个素数
3、使用opendir和readdir遍历指定目录下的所有*.c文件
/*****************/
#include <stdio.h>
#include <unistd.h>
main()
{
printf("before\n");
int pid = fork();
if(pid == 0)
{
while(1)
{
printf("child %d\n",pid);
sleep(1);
}
}
else
{
while(1)
{
printf("father %d\n",pid);
sleep(1);
}
}
printf("after %d\n",pid);
}
/*****************/
/*****************/
#include <curses.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
WINDOW *wtime,*wnumb;
main()
{
time_t tt;
struct tm *t;
int num = 0;
int i;
initscr();
wtime=derwin(stdscr,3,10,0,(COLS-10));
wnumb=derwin(stdscr,3,11,(LINES-3)/2,(COLS-11)/2);
box(wtime,0,0);
box(wnumb,0,0);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
if(fork())
{
while(1)
{
tt = time(0);
t = localtime(&tt);
mvwprintw(wtime,1,1,"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
sleep(1);
}
}
else
{
while(1)
{
num = 0;
for(i=0;i<7;i++)
{
num = num*10 + rand()%10;
}
mvwprintw(wnumb,1,2,"%7d",num);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
usleep(100000);
}
}
endwin();
}
/*****************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
void deal()
{
int status;
printf("回收中..\n");
wait(&status);
sleep(5);
printf("回收成功,status = %d\n",WEXITSTATUS(status));
}
main()
{
if(fork()==0)
{
printf("this is child process\n");
sleep(20);
exit(88);
}
else
{
signal(SIGCHLD,deal);
while(1)
{
printf("this is father process\n");
sleep(1);
}
}
}
chmod u+s main
echo $USER
int getuid() 得到实际用户(uid_t)
int geteuid() 得到有效用户(uid_t)
目录:
chdir 切换目录
mkdir 创建目录
rmdir 删除目录
unlink 删除文件
umassk 设置文件权限屏蔽位
stat 文件目录状态
fstat
目录遍历:
opendir man 3 opendir
readdir man 3 readdir
opendir
readdir man 2 readdir
scandir
seekdir
closedir
如果错误发生,一般返回NULL 或者 0
int scandir(const char *drip,//目录名
struct dirent ***namelist,//返回目录列表
int (*filter)(const struct dirent *),//回调函数,过滤目录 NULL 表示不过滤
int (*compar)(const struct dirent **,const struct dirent **)//排序返回目录, NULL 不排序
);
进程:
ps au
ps aue
ps a
top
pstree
向进程发送信号
kill -s 信号 进程id
kill -l 显示进程能接收的所有信号
system可以调用shell命令
int system(const char * command);
popen
FILE *popen(const char * command, const char *type);
int pclose(FILE *STREAM);
int fileno(FILE *stream);
函数fileno检测stream函数,返回它的整数形式的文件描述符。
替换当前进程的代码空间中的代码数据
函数本身不创建新的进程
exec execl
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
第一个参数:替换的程序
第二个参数...:命令行
命令行格式:命令名 选项参数
命令行结尾必须是空字符串
不创建新的进程
替换当前进程的代码
excel 搜索绝对路径
excelp 搜索相对路径
fork
1.创建进程
1.1int pid = fork();
1.2.新进程的代码是什么:克隆父进程的代码,且克隆了执行位置。父进程执行过的代码将不会执行
1.3.在子进程不调用fork语句所以返回值为0
1.4.父子进行同时进行
使用fork实现多任务
进程
线程
信号
异步
线程池
进程池
2.理解进程
2.1父子进程的关系
两个独立的进程
互为父子的关系 子进程节点树挂在父进程下
2.2问题:
2.2.1.父进程先结束
子进程就依托根进程init:孤儿进程
孤儿进程没有任何问题,没有任何的危害.
2.2.2.子进程先结束
子进程会成为僵尸进程
僵尸进程不占用内存,不占用CPU,但在进程任务管理树上占用一个节点
僵尸进程造成进程名额资源浪费
所以要处理僵尸进程
2.2.3.僵尸进程使用wait回收
#include <unistd.h>
void _exit(int status);
#include <stdlib.h>
void _Exit(int status);
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
2.2.4父进程怎么知道子进程退出?
子进程结束通常会想父进程发送一个信号
SIGCHLD
[alexliu@localhost day05]$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
2.2.5父进程会子进程退出信号
int signal(int sig,void(*fun)(int));
向系统注册:只要sig信号发送,系统停止进程,并调用fun函数
当函数执行完毕,继续原来的程序
2.2.5.1实现处理函数
2.2.5.2使用signal绑定信号与函数
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
2.2.6父子进程的资源访问
2.2.6.1内存资源2.2.6.2文件资源
说明:子进程克隆整个内存区域
但内存区域指向不同的物理空间
尽管克隆,但内存独立,不能互相访问
多进程实现多任务,进程之间的数据交换是大问题
inter process communication (IPC)
映射内存:
MAP_SHARED:映射到同一物理内存
MAP_PRIVATE:映射到不同的物理内存
int *a = mmap(0,4,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED,0,0);//父子进程可以访问*a
int *a = mmap(0,4,PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_PRIVATE,0,0);//父子进程不可以访问*a
int *a = sbrk(4);//私有的父子进程不可以访问*a
两个进程之间,文件描述符质量的是同一个文件内核号
结论:
进程的数据交换,基于两种方式:
共享内存:有序内存(管道,socket)、无序内存(mmap)
文件:有序文件、无序文件(普通文件)
基于内核对象:文件,内存,队列
回顾:
1、目录遍历
2、进程创建system popen exec fork
3、僵尸进程出现的条件及回收
4、利用多进程实现简单的任务
5、理解进程的克隆
作业:
1、使用两个进程,查找素数
A进程查找1-5000
B进程查找2001-10000
把素数写入文件
2、写一个多任务程序(两个进程数据共享)
A进程查找素数,放入mmap分配的空间
B进程把mmap的数据取出来,判定两个数据是否相邻,如果相邻则打印这两个素数
3、使用opendir和readdir遍历指定目录下的所有*.c文件
/*****************/
#include <stdio.h>
#include <unistd.h>
main()
{
printf("before\n");
int pid = fork();
if(pid == 0)
{
while(1)
{
printf("child %d\n",pid);
sleep(1);
}
}
else
{
while(1)
{
printf("father %d\n",pid);
sleep(1);
}
}
printf("after %d\n",pid);
}
/*****************/
/*****************/
#include <curses.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
WINDOW *wtime,*wnumb;
main()
{
time_t tt;
struct tm *t;
int num = 0;
int i;
initscr();
wtime=derwin(stdscr,3,10,0,(COLS-10));
wnumb=derwin(stdscr,3,11,(LINES-3)/2,(COLS-11)/2);
box(wtime,0,0);
box(wnumb,0,0);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
if(fork())
{
while(1)
{
tt = time(0);
t = localtime(&tt);
mvwprintw(wtime,1,1,"%02d:%02d:%02d",t->tm_hour,t->tm_min,t->tm_sec);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
sleep(1);
}
}
else
{
while(1)
{
num = 0;
for(i=0;i<7;i++)
{
num = num*10 + rand()%10;
}
mvwprintw(wnumb,1,2,"%7d",num);
refresh();
wrefresh(wtime);
wrefresh(wnumb);
usleep(100000);
}
}
endwin();
}
/*****************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
void deal()
{
int status;
printf("回收中..\n");
wait(&status);
sleep(5);
printf("回收成功,status = %d\n",WEXITSTATUS(status));
}
main()
{
if(fork()==0)
{
printf("this is child process\n");
sleep(20);
exit(88);
}
else
{
signal(SIGCHLD,deal);
while(1)
{
printf("this is father process\n");
sleep(1);
}
}
}