系统与网络编程
access使用
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int ret=-1;
ret=access(argv[1],F_OK);
if(ret==-1)
{
perror("access");
return -1;
}
else if(ret==0)
{
printf("file exist\n");
}
return 0;
}
//111已存在,222无
Paste_Image.png
#include <stdio.h>
#include <unistd.h>
int main(int argc,char *argv[])
{
int ret=-1;
ret=access(argv[1],W_OK|R_OK);
if(ret==-1)
{
perror("access");
return -1;
}
else if(ret==0)
{
printf("file exist\n");
}
return 0;
}
//查看用户可执行权限
Paste_Image.png
dir
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
//打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
DIR *pDir=(opendir(argv[1]));
if(pDir==NULL)
{
perror("opendir:");
return -1;
}
printf("opendir ok\n");
close (pDir);
return 0;
}
Paste_Image.png
int main(int argc,char *argv[])
{
//打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
DIR *pDir=(opendir(argv[1]));
if(pDir==NULL)
{
perror("opendir:");
return -1;
}
printf("opendir ok\n");
struct dirent *pDirent=NULL;
pDirent = readdir(pDir);
while(pDirent!=NULL)
{
printf("%s ",pDirent->d_name);
pDirent=readdir(pDir);
//readdir(pDir)每次都会获得目录里的信息
}
printf("\n");
close (pDir);
}
Paste_Image.png
- rewinddir(pDirent):返回到目录的头部
- mkdir(pathname,mode):创建一个目录
- rmdir(pDirent):删除一个目录
- stat:查看目标文件目录下的文件及属性
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
int main(int argc,char *argv[])
{
//打开指定的目录,打开失败返回NULL.成功则返回指向目录的指针.
DIR *pDir=(opendir(argv[1]));
if(pDir==NULL)
{
perror("opendir:");
return -1;
}
printf("opendir ok\n");
struct stat fileStat;
struct dirent *pDirent=NULL;
int ret=-1;
pDirent = readdir(pDir);
while(pDirent!=NULL)
{
printf("%s ",pDirent->d_name);
ret=stat(pDirent->d_name,&fileStat);
if(ret==0)
{
switch(fileStat.st_mode&S_IFMT)
{
case S_IFREG:printf("这是一个普通文件\n");break;
case S_IFDIR:printf("这是一个目录文件\n");break;
default:printf("其他类型的文件\n");break;
}
}
else if(ret==-1)
{
perror("stat");
break;
}
pDirent=readdir(pDir);
//readdir(pDir)每次都会获得目录里的信息
}
printf("\n");
closedir(pDir);
}
Paste_Image.png
进程
- 什么是进程
- 进程是操作系统结构的基础;是一个正在执行的 程序 ;计算机中正在运行的程序实例;可以分配给 处理器 并由处理器执行的一个实体;由单一顺序的执行显示,一个当前状态和一组相关的系统资源所 描述 的活动单元。
- 进程控制块
- 进程和程序的区别
- 程序生存期很长,进程运行开始到运行结束。程序可以开启多个进程,但是一个进程只对应一个程序。
- 查看进程的运行状态
- 如何查看正在运行的进程
- ps:当前终端由用户启动的进程
- ps-a:系统后台所有的进程
- 如何创建进程
- fork:父进程创建子进程,父进程会对子进程进行一次拷贝,其中使用的资源都会完全的拷贝一份。返回状态也会被拷贝一份到子进程。
- 子进程id返回给父进程,父进程传给子进程数值0,父进程若得到-1,说明子进程未成功执行
- ./xxx &后台运行
- 进程如何结束
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
pid_t pid=-1;
pid=fork();
if(pid>0)//父进程
{
printf("this is parent progress\n");
}
else if(pid==0)//子进程
{
printf("this is child progress\n");
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
while(1)
{}
printf("hello world\n");
return 0;
}
Paste_Image.png
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
pid_t pid=-1;
int iNum=0;
char caData[32]={'\0'};
//子进程创建后,与父进程属于两个相互独立的进程.
pid=fork();
//fork成功:将子进程的id返回给父进程的PID,将0返回子进程的pid,
//fork失败:返回-1给父进程的pid变量,子进程便不会被创建
if(pid>0)//父进程
{
printf("this is parent progress\n");
strcpy(caData,"this is parent progress\n");
iNum=3;//父进程执行3次,当结束时会显示终端~/1612/11/11.30....
}
else if(pid==0)//子进程
{
printf("this is child progress\n");
strcpy(caData,"this is child progress\n");
iNum=6;
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
int i=0;
for(;i<iNum;i++)
{
printf("%s",caData);
sleep(1);
}
printf("hello world\n");
return 0;
}
Paste_Image.png
- 僵尸进程:子进程挂了但是父进程很忙,导致子进程被杀死后无人收拾<defunct>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
pid_t pid=-1;
pid=fork();
if(pid>0)//父进程
{
printf("this is parent progress\n");
while(1)
{}
}
else if(pid==0)//子进程
{
printf("this is child progress\n");
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
while(1)
{}
printf("hello world\n");
return 0;
}
Paste_Image.png
- 僵尸进程
- 如果一个进程终止,但是其父进程尚未调用wait或者waitpid,对他进行清理,这时的进程状态称之为僵尸进程。任何进程在刚终止的时候都是僵尸进程,正常情况下僵尸进程会立刻被父进程清理。
- 僵尸进程的危害:
- 系统允许存在的进程数是有上限的。
- 若存在大量的僵尸进程,则可能创建新的进程由于没有
- 进程号分配而失败
- 僵尸进程处理方式
- 将子进程的善后处理方式交给祖宗进程处理
- A-->B-->C:将B进程kill,C进程将会交给祖宗进程来清理。
- 父进程自己调用响应函数来对子进程做善后处理
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid=-1;
pid=fork();
if(pid>0)//父进程
{
printf("this is parent progress\n");
wait(NULL);//阻塞等待子进程的结束,获得子进程的退出状态,并对子进程做出清理工作.
while(1)
{}
}
else if(pid==0)//子进程
{
printf("this is first child progress\n");
pid_t pid2=-1;
pid=fork();
if(pid2>0)
{
return 0;
}
else if(pid2==0)
{
printf("this is second child progress\n");
return 0;
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
return 0;
}
Paste_Image.png
Paste_Image.png
- 编程实现每一秒钟父进程向文件中写入信息,每一秒子进程显示文件大小。
#include <stdio.h>
#include <errno.h> //errno
#include <string.h> //strerror()
#include <unistd.h> //read() write()
/*open*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc,char *argv[])
{
pid_t pid=-1;
pid=fork();
int i=0;
if(pid>0)//父进程
{
int fd=-1;
fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
if(fd==-1)
{
printf("open error:%s\n",strerror(errno));
return -1;
}
char *pData="hello world";
while(1)
{
#if 1
write(fd,pData,strlen(pData));
printf("insert success\n");
sleep(1);
#endif
}
close(fd);
}
else if(pid==0)//子进程
{
int fd=-1;
fd=open(argv[1],O_RDWR|O_CREAT|O_APPEND,S_IRUSR|S_IWUSR|S_IRGRP);
off_t offset=-1;
while(1)
{
#if 1
offset=lseek(fd,0,SEEK_END);
if(offset==-1)
{
printf("lseek error:%s\n",strerror(errno));
}
else
{
printf("file size:%ld\n",offset);
}
sleep(1);
#endif
}
close(fd);
}
else if(pid=-1)//创建进程失败
{
perror("fork");
return -1;
}
return 0;
}
- 一个进程结束时会关闭所有的文件描述符,释放在用户空间分配的内存,但它的PCB还保留着,如果进程异常终止则保留着导致该进程终止的信号
- 如果正常终止则保留退出状态:在终端可以用“$?”来查看
- 父进程可以调用wait或waitpid获取这些信息,然后彻底清楚掉这个进程
homework
#include <stdio.h>
#include <errno.h>
#include <string.h>
//open stat
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>//read() write()
//dir
#include <dirent.h>
#include <stdlib.h>
#define PER_IO_BYTES 4096
//拷贝文件需要考虑目录文件及文本文件
int fileType(mode_t mode)//获得文件类型
{
int ret =-1;
switch(mode & S_IFMT)//S_IFMT:掩码,可获得该文件类型
{
case S_IFREG:
ret=0;
break;
case S_IFDIR:
ret=1;
break;
default:
ret=-1;
break;
}
return ret;
}
void copyRegularFile(const char *pDestPathname,
const char *pSrcPathname)//拷贝普通文件
{
if(pDestPathname==NULL||pSrcPathname==NULL)//形参有效性检查
{
return;
}
int iDestFd=-1;//以写的方式打开目标文件
iDestFd=open(pDestPathname,O_WRONLY|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if(iDestFd==-1)
{
perror("open dest");
exit(EXIT_FAILURE);//文件返回状态
}
int iSrcFd=-1;//以读的方式打开源文件
iSrcFd=open(pSrcPathname,O_RDONLY|O_CREAT,
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if(iSrcFd==-1)
{
perror("open src");
exit(EXIT_FAILURE);//文件返回状态
}
unsigned char caBuf[PER_IO_BYTES]={'\0'};
int ret=-1;
//从源文件循环读取数据
while(ret=read(iSrcFd,caBuf,PER_IO_BYTES))
{
//判断数据读取成功失败与否
if(ret==-1)
{
//如果发生的错误是EGAIN,EGAIR
//需要重新读取数据
if(errno=EAGAIN||errno==EINTR)
{
continue;
}
//如果是其他错误,则显示信息并退出程序
perror("read src");
// close(iSrcFd);
// close(iDestFd);
exit(EXIT_FAILURE);//文件返回状态
}
//如果返回值为0,表示已读到文件尾,没有数据可读
//则文件拷贝结束
else if(ret==0)
{
break;
}
while(1)
{ //将读到的数据写入到目标文件
ret=write(iDestFd,caBuf,ret);
if(ret==-1)
{
if(errno=EAGAIN||errno==EINTR)
{
continue;
}
perror("write dest");
// close(iSrcFd);
// close(iDestFd);
exit(EXIT_FAILURE);
}
break;
}
}
close(iSrcFd);
close(iDestFd);
}
void copyDirFile(const char *pDestDirName
, const char *pSrcDirName)
{
if (NULL == pDestDirName || NULL == pSrcDirName)
{
return;
}
int ret = -1;
ret = mkdir(pDestDirName, 0775);
if (-1 == ret)
{
if (EEXIST != errno)
{
perror("mkdir");
exit(EXIT_FAILURE);
}
}
DIR *pDestDir = NULL;
pDestDir = opendir(pDestDirName);
if (NULL == pDestDir)
{
perror("open dest dir");
exit(EXIT_FAILURE);
}
DIR *pSrcDir = NULL;
pSrcDir = opendir(pSrcDirName);
if (NULL == pSrcDir)
{
perror("open src dir");
exit(EXIT_FAILURE);
}
char caDestFileName[64] = {'\0'};
char caSrcFileName[64] = {'\0'};
struct stat fileStat;
struct dirent *pDirent = NULL;
pDirent = readdir(pSrcDir);
int iLen = 0;
while (NULL != pDirent)
{
if (0 != strcmp(pDirent->d_name, "..")
&& 0 != strcmp(pDirent->d_name, "."))
{
strcpy(caSrcFileName, pSrcDirName);
iLen = strlen(pSrcDirName);
if (pSrcDirName[iLen-1] != '/')
{
strcat(caSrcFileName, "/");
}
strcat(caSrcFileName, pDirent->d_name);
printf("%s\n", caSrcFileName);
/********************************************************/
strcpy(caDestFileName, pDestDirName);
iLen = strlen(pDestDirName);
if (pDestDirName[iLen-1] != '/')
{
strcat(caDestFileName, "/");
}
strcat(caDestFileName, pDirent->d_name);
/********************************************************/
ret = stat(caSrcFileName, &fileStat);
if (-1 == ret)
{
perror("stat");
exit(EXIT_FAILURE);
}
ret = fileType(fileStat.st_mode);
switch (ret)
{
case 0:
copyRegularFile(caDestFileName, caSrcFileName);
break;
case 1:
copyDirFile(caDestFileName, caSrcFileName);
break;
default:
break;
}
}
/********************************************************/
pDirent = readdir(pSrcDir);
}
}
int main(int argc,char *argv[])
{
copyDirFile(argv[2],argv[1]);
return 0;
}
网友评论