标签:
Linux应用编程学习笔记
周学伟
一.系统调用文件编程
1.文件打开函数
/*****************************************************************************
函数名:open
函数原型:int open(const char * pathname, int flags)
int open(const char * pathname,int flags,mode_t mode)
函数功能:打开或创建一个文件
所属头文件:<sys/types.h> <sys/stat.h> <fcntl.h>
返回值:成功时:返回的是文件描述符
失败时:返回-1
参数说明:pathname:打开文件的路径与文件名
Flags:打开方式
O_RDONLY:只读方式打开
O_WRONLY:只写方式打开
O_RDWE:读写模式
还有附加选项,选项通过”|”与上面链接
O_APPEND:每次写操作都写入文件的尾部
O_CREAT:如果指定文件不存在,则创建这个文件
Mode:前提是前面使用O_CREAT参数,创建这个文件并且以mode模式打开
****************************************************************************/
2.创建文件
/*****************************************************************************
函数名:creat
函数原型:int creat(const char * pathname,mode_t mode)
函数功能:创建一个文见并以只写的方式打开该文件
所属头文件:<sys/types.h> <sys/stat.h> <fcntl.h>
返回值:成功时:返回的是文件描述符
失败时:返回-1
参数说明:pathname:创建的文件的路径与文件名
Flags:创建文件读写权限
O_RDONLY:只读方式打开
O_WRONLY:只写方式打开
O_RDWE:读写模式
还有附加选项,选项通过”|”与上面链接
O_APPEND:每次写操作都写入文件的尾部
O_CREAT:如果指定文件不存在,则创建这个文件
Mode:前提是前面使用O_CREAT参数,创建这个文件并且以mode模式打开
****************************************************************************/
3.关闭文件
/*****************************************************************************
函数名:close
函数原型:int close(int fd)
函数功能:创建一个文见并以只写的方式打开该文件
所属头文件: <unistd.h>
返回值:成功时:返回0
失败时:返回-1
参数说明:fd:关闭文件的文件描述符
****************************************************************************/
4.读文件
/*****************************************************************************
函数名: read
函数原型:ssize_t read(int fd,void *buf,size_t count)
函数功能:读文件
所属头文件: <unistd.h>
返回值:成功时:返回读取的字节数
失败时:返回-1
参数说明:fd:要进行读操作的文件的文件描述符
buf:存储从fd所指向的文件中读取的数据
count:希望读取的字节数
****************************************************************************/
4.写文件
/*****************************************************************************
函数名:write
函数原型:ssize_t write(int fd,const void *buf,size_t ledgth)
函数功能:想指定文件写入数据
所属头文件: <unistd.h>
返回值:成功时:返回写入到文件中的的字节数
失败时:返回-1
参数说明:fd:要进行读操作的文件的文件描述符
buf:要写入数据的存放区
ledgth:希望写入的字节数
****************************************************************************/
5.文件定位
/*****************************************************************************
函数名:lseek
函数原型:off_t lseek(int fd,0ff_t offset int whence)
函数功能:重新定位文件的读写位置
所属头文件: <sys/types.h> <unistd.h>
返回值:成功时:返回移动后的文件指针距离文件头的位置
失败时:返回-1
参数说明:fd:要进行操作的文件的文件描述符
Offset:从whence所指的位置开始向前或向后移动Offset个偏移量
whence:文件指针起始位置。取值如下:
SEEK_SET:文件指针起始位置在文件头部
SEEK_CUR:文件指针起始位置在文件当前位置
SEEK_END:文件指针起始位置在文件尾部
****************************************************************************/
6.复制文件的描述符
/*****************************************************************************
函数名:dup
函数原型:int dup(int oldfd)
函数功能:复制文件描述符
所属头文件: <unistd.h>
返回值:成功时:返回新的文件描述符
失败时:返回-1
参数说明:oldfd:待复制的老的文件描述符
****************************************************************************/
文件说明:文件拷贝函数
创建日期:2014.11.25
创建者:周学伟
函数说明:./text start.S cpdfile
-----------------------------------------------------------------------------------------------------------------
#include <sys/types.h> <sys/stat.h> <unistd.h> <fcntl.h>
void main(int argc, char ** argv)
{
int fd_s,fd_d;
char buf[512];
int count = 0;
/***打开源文件***/
fd_s = open(argv[1],O_RDONLY);
/***打开或创建目标文件***/
fd_d = open(argv[2],O_RDWR|O_CREAT,0666);
read(fd_s,buf,512);
/***循环读取所有内容***/
while((count = read(fd_s,buf,512))>0)
{
write(fd_d,buf,count);
}
close(fd_s);
close(fd_d);
}
二.库函数访问文件编程
1.打开文件
/*****************************************************************************
函数名:fopen
函数原型:FILE * fopen(const char * path,const char * mode)
函数功能:打开文件
所属头文件: <stdio.h>
返回值:成功时:返回文件的指针
失败时:返回空指针NULL
参数说明:path:文件的名字,包含路径
Mode:打开方式,参数如下:
“r”:以只读方式打开文件
“r+”:以可读可写方式打开文件
“w”:以只写方式打开文件,若文件不存在则创建该文件
“w+”::以可读可写方式打开文件,若文件不存在则创建该文件否则 文件会被清空
“a”:以追加方式打开只写文件,若文件不存在则创建该文件,若文件
存在写入的数据会追加到文件尾部。原先文件内容会被保存
“a”:以追加方式打开可读可写文件,若文件不存在则创建该文件,
****************************************************************************/
2.关闭文件
/*****************************************************************************
函数名:fclose
函数原型:int fclose(FILE *fp )
函数功能:关闭打开的文件
所属头文件: <stdio.h>
返回值:成功时:返回0
失败时:返回EOF
参数说明:fp:关闭fp指向指向的文件的指针
****************************************************************************/
3.读文件
/*****************************************************************************
函数名:fread
函数原型:size_t fread(void *ptr.size _t size,size_t named,FILE * stream)
函数功能:从文件中读取数据
所属头文件: <stdio.h>
返回值:成功时:返回成功读取到的数据量
失败时:返回0
参数说明:stream:指向要读取数据的文件
Ptr:指向读取到的数据存放的位置
Size:每块数据中每次读取的数据大小Size
Named:读取Named块数据
****************************************************************************/
4.写文件
/*****************************************************************************
函数名:fwrite
函数原型:size_t fwrite (const void *buffer .size _t size,size_t named,FILE * stream)
函数功能:向文件中写入数据
所属头文件: <stdio.h>
返回值:成功时:返回成功写入到的数据量
失败时:返回0
参数说明:stream:指向要写入数据的文件
buffer:存放要写入文件的数据
Size:每块数据中每次写入的数据大小Size
Named:写入Named块数据
****************************************************************************/
5.定位文件
/*****************************************************************************
函数名:fseek
函数原型:size_t fseek (FILE * stream,long offset,int origin)
函数功能:重新定位文件的读写位置
所属头文件: <stdio.h>
返回值:成功时:返回0
失败时:返回-1
参数说明:stream:指向要写入数据的文件
Offset:偏移量,正数表示正向移动,复数表示负向移动
Origin:文件指针起始位置。取值如下:
SEEK_SET:文件指针起始位置在文件头部
SEEK_CUR:文件指针起始位置在文件当前位置
SEEK_END:文件指针起始位置在文件尾部
(可用数字一次表示为:0, 1, 2)
****************************************************************************/
三.时间编程
4.获取日历时间
/*****************************************************************************
函数名:time
函数原型:time_t time (time_t * time)
函数功能:获取当前的系统时间
所属头文件: <time.h>
返回值:成功时:返回日历时间(秒数)
失败时:返回-1
参数说明:time:不为空的情况下,保存从1970.1.1.0点0分0秒到现在的秒数
****************************************************************************/
5.获取格林威治时间
/*****************************************************************************
函数名:gmtime
函数原型:struct tm *gmtime (const time_t *clock)
函数功能:通过日历时间转化成格林威治时间(世界标准时间)
所属头文件: <time.h>
返回值:成功时:返回世界标准时间,以struct tm 结构返回
失败时:返回NULL
参数说明:clock:待转化的时间
****************************************************************************/
6.获取本地时间
/*****************************************************************************
函数名:localtime
函数原型:struct tm *localtime (const time_t *clock)
函数功能:获取本地时间
所属头文件: <time.h>
返回值:成功时:返回本地时间,返回值以struct tm结构返回
失败时:返回NULL
参数说明:clock:指向待转化的日历时间的指针变量
****************************************************************************/
7.以字符串格式本地时间
/*****************************************************************************
函数名:asctime
函数原型:char *ascltime (const struvt tmt *clock)
函数功能:把tm格式存放的时间转化为字符串格式
所属头文件: <time.h>
返回值:成功时:返回字符串格式的时间
失败时:返回NULL
参数说明:clock:待转化的tm格式的时间
****************************************************************************/
8获取高精度的时间
/*****************************************************************************
函数名:gettimeofday
函数原型:int gettimeofday(struct timeval *tv, struct timezone *tz)
函数功能:获取到本地高精度的时间
所属头文件:<sys/time.h>
返回值:成功时:返回0
失败时:返回-1
参数说明:tv:指向包含秒和微妙的结构(从1970.1.1.0点0分0秒到现在)
tz:通常为空NULL
****************************************************************************/
四.进程控制理论
1.获取进程的PID
/*****************************************************************************
函数名:getpid
函数原型:pid_t getpid(void)
函数功能:获取调用getpid的进程的PID
所属头文件:<unistd.h> <sys/types.h>
返回值:成功时:返回调用进程的ID
参数说明:无
****************************************************************************/
2.创建一个子进程
/*****************************************************************************
函数名:fork
函数原型:pid_t fork(void)
特殊说明:1.运行次序不一定
2.子进程拥有自己独立的栈区
3.子进程只能用exit()函数退出,父进程可用exit()函数也可用return退出
函数功能:创建一个子进程
所属头文件:<unistd.h>
返回值:成功时:子进程中:返回0
父进程中:返回子进程的ID
失败时:返回-1
参数说明:无
****************************************************************************/
3.创建一个子进程
/*****************************************************************************
函数名:vfork
函数原型:pid_t vfork(void)
特殊说明:1.一定是子进程先运行。
2.子进程和父进程共享同一片栈区
3.子进程只能用exit()函数退出,父进程可用exit()函数也可用return退出
函数功能:创建一个子进程,并阻塞父进程,
所属头文件:<unistd.h> <sys/types.h>
返回值:成功时:子进程中:返回0
父进程中:返回子进程的ID
失败时:返回-1
参数说明:无
****************************************************************************/
4.进程等待
/*****************************************************************************
函数名:wait
函数原型:pid_t wait(int *status)
函数功能:挂起调用它的子进程,知道其子进程结束
所属头文件:<sys/types.h> <sys/wait.h>
返回值:成功时:返回终止的那个子进程的ID
失败时:返回-1
参数说明:status:记录子进程退出的原因
****************************************************************************/
5.运行程序
/*****************************************************************************
函数名:execl
函数原型:int execl(const char *path,const char *arg........)
函数功能:运行可执行的程序
所属头文件:<unistd.h>
返回值:成功时:不返回
失败时:返回-1
参数说明:path:表示要运行的可执行文件路径
Arg:可执行文件运行所需的参数,以空指针NULL结束
调用例程:execl(“/bin/ls”,”ls”,”/home”,NULL);
特殊说明:如果调用execl函数整个程序的代码段全部变成ls下面的代码了。
在原来的进程中,用新的代码段替换原有的程序,执行新的程序。
****************************************************************************/
6.运行程序
/*****************************************************************************
函数名:system
函数原型:int system(const char *command)
函数功能:运行可执行的程序
所属头文件:<unistd.h>
返回值:成功时:返回一个状态值
失败时:返回-1
参数说明:command:被执行的命令,字符串格式
调用例程:execl(“/bin/ls”,”ls”,”/home”,NULL);
特殊说明:如果调用execl函数整个程序的代码段全部变成ls下面的代码了。
在原来的进程中,先执行system中的命令,在执行其后的数据。
新的代码段不会替换原有的程序。
****************************************************************************/
五.进程间的通信
/*****************************************************************************
1通信方式:A.无名管道和有名管道(数据传输)
B.信号(时间通知)
C.信号量(资源共享)
D.消息队列
E.共享内存
F.套接字
2.特殊说明:A.无名管道只能用于子进程和父进程间通信。
B.有名管道可用于任意两个进程之间通信。
C.管道通信是单向的,有固定的读端和写端
D.取走数据后,管道为空。
E.若管道为空,读取时读进程阻塞,直到有数据可读。
****************************************************************************/
1.无名管道编程
/*****************************************************************************
函数名:pipe
函数原型:int pipe(int fd[2])
函数功能:创建一个无名管道
所属头文件:<unistd.h>
返回值:成功时:返回0
失败时:返回-1
参数说明:fd[0]:指向读端
fd[1]:指向写端
特殊说明:可以使用write(),read(),close()等函数操作数据
****************************************************************************/
2.有名管道编程
1,创建有名管道
/*****************************************************************************
函数名:mkfifo
函数原型:int mkfifo(const char *pathname,mode_t mode)
函数功能:创建一个无名管道
所属头文件:<sys/types.h> <sys/stat.h>
返回值:成功时:返回0
失败时:返回-1,错误原因存放于errno
参数说明:pathname:创建有名管道对应的实名文件路径。该文件必须不存在
mode:文件的权限
特殊说明:可以使用write(),read(),close()等函数操作数据。
读FIFO文件的进程只能以RDONLY权限读取。
写FIFO文件的进程只能以WRONLY权限写入数据。
读完FIFO文件后,文件内容为空。
****************************************************************************/
例程分析:
#include <stdio.h> <sys/wait.h> <unistd.h> <sys/types.h>
void main()
{
int pipefd[2]; pid_t pid1=0; char buffer[10];
pipe(pipefd);
pid1 = fork();
if(pid1>0)
{
write(pipefd[1],"zhou",5);
wait(NULL); close(pipefd[1]); exit(0);
}
if(pid1==0)
{
read(pipefd[0],buffer,5);
close(pipefd[0]); printf("read is data: %s\n",buffer); exit(0);
}
}
---------------------------------------------------------------------------------------------------------------------
1,删除有名管道
/*****************************************************************************
函数名:unlink
函数原型:int unlink(const char *pathname)
函数功能:删除有名管道(有名管道的实质是一个特殊文件)
所属头文件:<unistd.h>
返回值:成功时:返回0
失败时:返回-1,错误原因存放于errno
参数说明:pathname:创建有名管道对应的实名文件路径名。
****************************************************************************/
例程分析:
/***********************************写进程代码*******************************/
#include <sys/types.h> <sys/stat.h> <unistd.h> <fcntl.h>
void main()
{
int fd=0;
mkfifo("/home/fifo",0666);
fd = open("/home/fifo",O_WRONLY);
write(fd,"zhouxue",8);
close(fd);
}
/*****************************读进程代码********************************/
#include <sys/types.h> <sys/stat.h> <unistd.h> <fcntl.h>
void main()
{
int fd=0;
char buffer[10];
fd = open("/home/fifo",O_RDONLY);
read(fd,buffer,8);
printf("read data is %s\n",buffer);
close(fd);
unlink("/home/fifo");
}
-------------------------------------------------------------------------------------------------------------------
3信号通信
说明:linux当中所有的信号都定义在/usr/include/asm/signal.h中
常用信号标志:SIGKILL:该信号结束接收该信号的进程
SIGSTOP:来自键盘或调试程序的停止信号
SIGINT:来自键盘的中断信号
SIGHUP:从终端上发出的结束信号
SIGHLD:子进程停止或结束时通知父进程的信号
------------------------------------------------------------------------------------------------------------------
1,发送信号
/*****************************************************************************
函数名:kill
函数原型:int kill(pid_t pid,int sig)
函数功能:向一个进程发送信号
所属头文件:<signal.h> <sys/types.h>
返回值:成功时:返回0
失败时:返回-1
参数说明:Sig:用来指明要发送的信号。
pid:pid>0:指向接收信号进程的PID。
Pid=0:将信号发送给目前进程相同进程组的所有进程。
Pid=-1:将信号广播发送给系统所有的进程。
Pid<0:将信号发送给进程组识别码为pid绝对值的所有进程。
****************************************************************************/
2设置信号处理的方式
/*****************************************************************************
函数名:signal
函数原型:sig_t signal(int signum, sig_t handler)
Void(*signal(int signum, void(*handler)(int)))(int)
Typedef void(*sig_t)(int)
函数功能:信号处理
所属头文件:<signal.h>
返回值:成功时:返回先前的信号处理函数指针
失败时:返回SIGERR(-1)
参数说明:signum:设置辛亥处理函数所依赖的信号编号
Handler:信号处理函数
如果handler不是函数指针,则必须是下列常数之一
SIG_IGN:忽略参数signum指定的信号
SIG_DFL:将参数signum指定的信号重设为预设的信号处理方式
第三:用户自己编写一个信号处理函数来处理
****************************************************************************/
3,进程等待
/*****************************************************************************
函数名:pause
函数原型:int pause(void)
函数功能:让进程暂停直到信号出现
所属头文件:<unistd.h>
返回值:只返回-1
参数说明:无
****************************************************************************/
代码分析:
-------------------------------------------------------------------------------------------------------------------
/******************************进程处理******************************/
#include <unistd.h> <sys/types.h> <stdio.h> <signal.h>
void main(int argc,char *argv[])
{
pid_t pid;
pid = atoi(argv[1]);
kill(pid,SIGINT);
}
/******************************发送信号给进程******************************/
#include <unistd.h> <signal.h> <stdio.h>
void myfunc(int a)
{
printf("the signal to dell\n");
}
void main()
{
signal(SIGINT,myfunc);
pause();
}
----------------------------------------------------------------------------------------------------------------------
七.信号量互斥编程
/*****************************************************************************
1创建和打开信号量
/*****************************************************************************
函数名:semget
函数原型:int semget(key_ key,int nsems,int semflag)
函数功能:打开信号量,当Key所指定的信号量不存在的时候,并且Semflag标识中
包含了IPC-CREAT标志时,去创建一个信号量集合。
所属头文件:<sys/types.h> <sys/ipc.h> <sys/sem.h>
返回值:成功:返回信号量的IPC标示符,
失败:返回-1,错误原因保存在errno中
EACCESS:没有权限。
EEXIST:信号灯已经存在,无法创建。
EIDRM:信号灯集已经删除。
ENOENT:信号灯集不存在,同时没有使用IPC_CREAT.
ENOMEM:没有足够的内存创建信号灯集。
ENOSPC:超出限制。
参数说明:key:要打开的信号量的键值,可用ftok()函数获取。
Nsems:创建的信号量集合中的个数。
Semflag:表示操作类型,也可用于信号灯的访问权限。
****************************************************************************/
2获得IPC键值
/*****************************************************************************
函数名:ftok
函数原型:key_t ftok(const char *pathname,int pid_id)
函数功能:通过文件路径名和子序列,获得system V IPC键值
所属头文件:<sys/types.h> <sys/ipc.h>
返回值:成功:返回信号量的IPC键值,
失败:返回-1,错误原因保存在errno中
参数说明:pathname:指定的带路径的文件名
Pid_id:子序列id,或工程id
****************************************************************************/
3操作信号量
/*****************************************************************************
函数名:semop
函数原型:int semop(int semid, struct sembuf *sops, unsigned nsops)
函数功能:操作信号量集合里面的信号灯
所属头文件:<sys/types.h> <sys/ipc.h> <sys/sem.h>
返回值:成功:返回共享内存的起始地址。
失败:返回-1。
参数说明:semid:要操作信号量集的标示符。
Sops:指向待操作的的结构体(数组),sembuf 结构体包含了对某个信号灯的
操作方法的信息,其成员如下:
Unsigned short sem_num:要操作的信号灯编号, 从0开始。
Short sem_op:为正数时代表释放信号灯。
为负数时代表获取信号灯,获取失败,进程等待。
Short sem_flag:操作信号灯的标识。
Nsops:用来指定要操作的信号量个数
****************************************************************************/
4初始化信号量
/*****************************************************************************
函数名:semctl
函数原型:int semctl(int semid, int semnum, int cmd,union semun arg)
函数功能:操作信号量集合里面的信号灯
所属头文件:<sys/types.h> <sys/ipc.h> <sys/sem.h>
返回值:成功:返回命令相关的正数
失败:返回-1。
参数说明:semid:信号灯的ID。
semnum:操作信号灯的编号。
cmd:控制命令,常用的命令有:
IPC_RMID:将信号灯集从内存从中删除。
GETPID:获得信号灯的ID。
GATVAL:获得信号灯的ID。
SETVAL:设置信号灯的ID。
Arg:是一个共同体类型的副本,其中各个量的使用情况和cmd设置有关。
****************************************************************************/
参考例程:
-----------------------------------------------------------------------------------------------------------------
/*************************A进程创建信号量*******************************/
#include <unistd.h> <sys/sem.h> <sys/types.h>
#include <sys/stat.h> <fcntl.h> <sys/ipc.h>
void main()
{
int fd = 0 ; int sops_flag,rest = 0; key_t key;
struct sembuf sops;
/*获取键值*/
key = ftok("/home/",1);
/*创建信号量*/
sops_flag = semget(key,1,IPC_CREAT);
/*获取信号量*/
rest = semctl(sops_flag,0,SETVAL,1);
printf("the init sopo is: %d\n",rest);
sops.sem_num = 0;
sops.sem_op = -1;
semop(sops_flag,&sops,1);
/*打开文件*/
fd = open("/home/txt.c",O_RDWR|O_APPEND);
write(fd,"math cless",11);
sleep(5);//等待信号
write(fd,"is quxiao",10);
/*释放信号量*/
sops.sem_num = 0;
sops.sem_op = +1;
semop(sops_flag,&sops,1);
close(fd);
}
/*****************************B进程写文件***********************************/
#include <unistd.h> <sys/sem.h> <sys/ipc.h>
#include <sys/types.h> <sys/stat.h> <fcntl.h>
void main()
{
int fd = 0; key_t key; int sops_flag; struct sembuf sops; int rest = 0;
/*获取键值*/
key = ftok("/home/",1);
/*创建信号量*/
sops_flag = semget(key,1,IPC_CREAT);
rest = semctl(sops_flag,0,GETVAL);
printf("the valye is %d\n",rest);
/*获取信号量*/
sops.sem_num = 0;
sops.sem_op = -1;
semop(sops_flag,&sops,1);
fd = open("/home/txt.c",O_RDWR|O_APPEND);
write(fd,"einglish cless",15);
sleep(5);
write(fd,"is exam",8);
/*释放信号量*/
sops.sem_num = 0;
sops.sem_op = +1;
semop(sops_flag,&sops,1);
close(fd);
}
---------------------------------------------------------------------------------------------------------------------
八.信号量同步编程
/*****************************************************************************/
信号同步编程有生产者和消费者:
1.生产者要做的有两件事:A.创建信号量。
B.初始化信号量为0。
C.只释放信号量能不获取信号量。
2.消费者要做的事:A.创建信号量。
B.只获取信号量不释放信号量。
例程分析:
----------------------------------------------------------------------------------------------------------------------/********************************生产者代码***********************************/
#include <unistd.h>
#include <fcntl.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/ipc.h>
void main()
{
int fd=0,rest=0,sops_flag=0,key=0;
struct sembuf sops;
key = ftok("/home/",1);
sops_flag = semget(key,1,IPC_CREAT);
rest = semctl(sops_flag,0,SETVAL,0) ;
fd = open("./txt.c",O_RDWR|O_CREAT,0775);
sleep(10);
write(fd,"the data write seccussed",25);
sops.sem_num = 0;
sops.sem_op = +1;
sops.sem_flag = SEC_UNDO;
semop(sops_flag,&sops,1);
close(fd);
}
/*******************************消费者代码********************************/
#include <unistd.h>
#include <fcntl.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <stdlib.h>
void main()
{
int fd=0,rest=0,sops_flag=0,key=0;
struct sembuf sops;
key = ftok("/home/",1);
sops_flag = semget(key,1,IPC_CREAT);
sops.sem_num = 0;
sops.sem_op = -1;
sops.sem_flag = SEC_UNDO;
semop(sops_flag,&sops,1);
system("cp ./txt.c ./txt1.c");
}
周学伟
2014.11.27
标签:
原文地址:http://www.cnblogs.com/zxouxuewei/p/4937046.html