linux 进程控制 时间,linux应用程序设计(一)——文件、时间编程及进程控制

本文中的代码是国嵌实验手册上的,并非原创,自己添上注释。

第一部分:文件编程

linux中文件编程可以使用两种方式:linux系统调用和C语言库函数。前者依赖于linux系统,后者和操作系统是独立的,在任何操作系统下,使用C语言库函数操作文件的方法都是相同的。

实验2-1-1文件编程—文件创建

一、源代码及注释

/*需求:创建一个可读可写的文件*/

#include /*输入输出头文件*/

#include /*实用函数头文件*/

#include /*类型头文件*/

#include /*文件状态头文件*/

#include /*文件控制头文件*/

void create_file(char *filename)

{

/*判断创建的文件是否成功*/

if(creat(filename,0666)<0)/*若创建成功内核向进程返回文件描述符(非负数)*/

{

printf("create file %s failure!\n",filename);

exit(EXIT_FAILURE);

}

else

printf("create file %s success!\n",filename);

}

/*函数功能:主函数*/

int main(int argc,char *argv[]) /*argc是命令行参数的数目,argv是指向参数的各指针所构成的数组(指针数组)*/

{

/*判断用户是否输入文件名*/

if(argc<2) /*命令行参数只有本程序文件名*/

{

printf("you haven't input filename,please try again!\n");

exit(EXIT_FAILURE);/*正常结束进程函数,终止状态为EXIT_FAILURE=1,在终端echo $?打印终止码*/

}

create_file(argv[1]);

exit(EXIT_SUCCESS);

}

二、详点说明

1、文件创建函数creat的参数说明——“0666”,不难理解6代表的是可读可写,在运行该程序后,创建出的文件的权限是这样的“-rw-r--r--",即真正可读可写的只有该用户自己。

2、exit()和return()函数的区别:

exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束。

return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一层调用。

实验2-2-2          文件编程——文件拷贝

一、源代码

/*使用库函数实现文件copy功能*/

#include #include #include #define BUFFER_SIZE 1024

int main(int argc,char *argv[])

{

FILE *from_fd;   //定义FILE结构体,存放打开源文件返回值

FILE *to_fd;

long file_len=0;

char buffer[BUFFER_SIZE];

/*判断入参是否为三,即本文件名,源文件名和目的文件名*/

if(argc!=3)

{

printf("Usage:%s fromfile tofile\n",argv[0]);

exit(EXIT_FALURE);

}

/*打开源文件*/

if((from_fd=fopen(argv[1],"rb"))==NULL)

{

printf("Open %s Error!\n",argv[1]);

exit(EXIT_FALURE);

}

/*创建目的文件*/

if((to_fd=fopen(argv[2],"wb"))==NULL)

{

printf("Open %s Error!\n",argv[2]);

exit(EXIT_FALURE);

}

/*测试源文件大小*/

fseek(from_fd,0L,SEEK_END);   //将源文件指针指到文件尾

file_len=ftell(from_fd);      //取得文件指针位置,返回位置值,即文件大小

fseek(from_fd,0L,SEEK_SET);   //将源文件指针指回到文件头

printf("from file size is %d\n",file_len);

/*进行文件拷贝*/

while(!feof(from_fd))    //检查文件指针是否到了文件尾

{

fread(buffer,BUFFER_SIZE,1,from_fd);  //从源文件读取BUFFER_SIZE*1,存入buffer中

/*判断能否一次写完*/

if(BUFFER_SIZE>=file_len)

{

fwrite(buffer,BUFFER_SIZE,1,to_fd);

}

else

{

fwrite(buffer,file_len,1,to_fd);

file_len=file_len-BUFFER_SIZE;

}

memset(buffer,0,BUFFER_SIZE);  //将buffer中长度BUFFER_SIZE的数据写零

}

fclose(from_fd);

fclose(to_fd);

exit(EXIT_SUCCESS);

}

二、详点说明

1、关于FILE结构体:FILE定义的数据类型是一种结构体类型,FILE结构体与具体的编译器和系统有关。Linux系统下,在/usr/include/stdio.h中定义为typedef struct_IO_FILE  FILE,即一种结构体类型。

2、源程序中本来使用bzero()函数将buffer清零,故了解下这两个函数的用法和区别:

bzero原型:void bzero(void *s,int n);

用法:#include

功能:置字符串s的前n个字节为零且包括'\0'。

说明:bzero无返回值,并且使用strings.h头文件,strings.h曾经是POSIX标准的一部分,但是在POSIX.1-2001标准里面,这些函数被标记为了遗留函数而不推荐使用。在POSIX.1-2008标准里已经没有这些函数了。推荐使用memset替代bzero。

第二部分:时间编程

首先了解下三种时间类型:格林威治时间、日历时间(从某一标准时间点到此时经过的秒数)、本地时间。

实验2-1-3时间编程——获取本地时间

一、源代码

/*获取本地时间,以字符串形式显示*/

#include #include int main()

{

time_t lt;        //定义time_t结构(实际就是long类型)变量lt,存放日历时间,即秒数

struct tm *ptr;   //定义TM结构类型变量,以TM结构存放时间信息

/*获取日历时间*/

lt=time(NULL);

/*转换为本地时间*/

ptr=localtime(&lt);

/*以本地时间的字符串方式打印*/

printf("%s\n",asctime(ptr));

/*以本地时间的字符串方式打印*/

printf("%s\n",ctime(&lt));

return 0;

}

第三部分:进程控制

进程有三种状态:就绪态、执行态、阻塞态。

实验2-2-1fork创建子进程

一、源代码

/*需求:编写程序创建一子进程,分别在父进程和子进程中打印进程ID*/

#include /*linux标准头文件*/

#include /*类型头文件*/

#include #include #include #include /*错误号头文件*/

int main(void)

{

pid_t child;

/*创建子进程*/

if((child=fork())<0)

{

printf("Fork Error:%s\n",strerror(errno)); /*通过参数errno将错误号,转换为输出错误信息*/

exit(1);

}

else

if(child==0)  //子进程

{

printf("I am the child:%d\n",getpid());

exit(0);

}

else  //父进程

{

printf("I am the father:%d\n",getpid());

return 0;

}

}

实验2-2-2vfork创建子进程

一、源代码

/*需求:编写程序使用vfork创建一子进程,分别在父进程和子进程中打印进程ID,并观察父子进程的运行顺序*/

#include /*linux标准头文件*/

#include /*类型头文件*/

#include #include #include /*错误号头文件*/

int main(void)

{

pid_t child;

/*创建子进程*/

if((child=vfork())<0)

{

printf("Fork Error:%s\n",strerror(errno));

exit(1);

}

else

if(child==0)  //子进程

{

sleep(1);  //子进程睡眠一秒

printf("I am the child:%d\n",getpid());

exit(0);

}

else  //父进程

{

printf("I am the father:%d\n",getpid());

return 0;

}

}

二、详点说明

fork与vfork的区别:

1、fork:子进程拷贝父进程的数据段,即子进程创建后与父进程相互独立运行

vfork:子进程共享父进程的数据段。

2、fork:父、子进程的运行顺序不确定

vfork:父进程必须等待子进程运行结束才能运行。

实验2-2-3exec函数族

一、源代码

/*需求:使用系统调用execl函数创建一个文件*/

#include #include #include int main(int agrc,char *argv[])

{

/*判断入参有没有传入文件名*/

if(agrc<2)

{

perror("You haven't input the filename,please try again!\n");

exit(1);

}

/*调用execl函数,用可执行程序file_creat替换本进程*/

if(execl("./file_creat","file_creat",argv[1],NULL)<0)

perror("execl error!\n");    /*perror将你输入的信息和errno对应的错误信息一起打印出来*/

}

二、详点说明

perror函数、strerror函数、erron的关系和区别:

1、errno是错误码,在errno.h头文件中;

2、strerror函数,通过参数errno将错误码对应的错误信息返回;

3、perror函数,将你输入的信息和errno对应的错误信息一起返回。

实验2-2-4进程等待

一、源代码

/*需求:编写程序创建一子进程,父进程需要等待子进程运行完后才能执行*/

#include /*linux标准头文件*/

#include /*类型头文件*/

#include /*等待调用头文件*/

#include #include #include /*错误号头文件*/

int main(void)

{

pid_t child;

/*创建子进程*/

if((child=fork())<0)

{

printf("Fork Error:%s\n",strerror(errno));

exit(1);

}

else

if(child==0)  //子进程

{

printf("the child process is run\n");

sleep(1);  //子进程睡眠一秒钟,但并没有去执行父进程

printf("I am the child:%d\n",getpid());

exit(0);

}

else  //父进程

{

wait(NULL); //阻塞父进程,直到子进程退出

printf("the father process is run\n");

printf("I am the father:%d\n",getpid());

return 0;

}

}

二、详点说明

wait()参数设置为NULL,将不返回子进程结束状态值。

最后,附上个人觉得比较有用的上网资料

Linux 常用C函数点击打开链接

Linux头文件汇总                 点击打开链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值