Linux 进程的基本控制—atexit、on_exit函数、文件锁

进程的基本控制:

进程控制函数:pause、sleep、usleep

函数atexit on_exit

atexit函数:

#include<stdlib.h>

功能:注册终止函数(即进程执行结束后调用的函数)

用法:int atexit( void (*func)(void)); (参数为回调函数)

注意:按照ISO C的规定,一个进程可以登记多达32个函数,这些函数将由exit自动调用。atexit()注册的函数类型应为不接受任何参数的void函数,exit调用这些注册函数的顺序与它们登记时候的顺序相反。同一个函数如若登记多次,则也会被调用多次

例子:

#include<stdio.h>

#include<stdlib.h>

voidfunc()

{

printf(“over\n”);

}

voidmain()

{

atexit(func);

printf(“进程:\n”);

}

运行结果:

进程:

over

说明:在进程结束时,会自动调用atexit函数的参数的回调函数,我们可以在这个回调函数中做一些操作,比如释放一些资源。

例子2:

#include<stdio.h>

#include<stdlib.h>

voidfun1()

{

printf(“fun1被调用!\n”);

}

voidfun2()

{

printf(“fun2被调用!\n”);

}

voidfun3()

{

printf(“fun3被调用!\n”);

}

intmain()

{

atexit(fun1);

atexit(fun2);

atexit(fun3);

printf(“进程结束!\n”);

}

运行结果:

进程结束!

fun3被调用!

fun2被调用!

fun1被调用!

说明:进程结束所调用的回调函数,与其注册的顺序相反。

on_exit函数:

on_exit()函数式atexit函数的扩展

表头文件 #include<stdlib.h>   

定义函数 int on_exit(void (*function)(int, void*),void *arg);

参数arg 指针会传给参数function函数

function 的第一个参数是进程结束的返回码,第二个void指针参数为从on_exit函数中的参数arg传过来的。

返回值如果执行成功则返回0,否则返回-1,失败原因存于errno中  

例子:

 #include<stdlib.h>
  void my_exit(int status,void *arg)
  {
printf(“before exit()!\n”);
printf(“exit (%d)\n”,status);
printf(“arg = %s\n”,(char*)arg);

}

main()
{
 char * str=”test”;
on_exit(my_exit,(void*)str);

exit(12);

}
执行
before exit()!
exit (12)

arg = test

进程与文件锁:

在多进程下文件读写是共享的

问题:

怎么知道一个文件正在被另一个进程读写?

解决方案:

文件锁(建议锁)

API函数:

fcntl(文件锁受内核参数影响)

编程技巧:

对文件加锁

判断一个文件是否存在锁

函数说明:

int fcntl(

int fd,//被加锁的文件描述符

int cnd,//加锁方式:F_SETLK(已经加锁则返回异常) F_SETLKW(已经加锁,堵塞等在,直到它减锁)F_UNLK

struct flock *lk);//锁的描述

返回值:

0:加锁成功

-1:加锁失败

结构体flock的指针:
struct flcok
{
short int l_type; /* 锁定的状态*/

//以下的三个参数用于分段对文件加锁,若对整个文件加锁,则:l_whence=SEEK_SET, l_start=0, l_len=0
short int l_whence; /*决定l_start位置*/
off_t l_start; /*锁定区域的开头位置*/
off_t l_len; /*锁定区域的大小*/

pid_t l_pid; /*锁定动作的进程*/
};

l_type 有三种状态:
F_RDLCK 建立一个供读取用的锁定
F_WRLCK 建立一个供写入用的锁定
F_UNLCK 删除之前建立的锁定

_whence 也有三种方式:
SEEK_SET 以文件开头为锁定的起始位置
SEEK_CUR 以目前文件读写位置为锁定的起始位置
SEEK_END 以文件结尾为锁定的起始位置

案例:

写两个程序:

A:加锁

B:获取锁的信息

1. 加锁程序

Setlock.c

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<fcntl.h>

void main()

{

int fd;

struct flock lk;

int r;

//打开文件

fd=open(“text.txt”,O_RDWR);

if(fd==0)

{

printf(“open error:%m\n”);

exit(-1);

}

//描述锁

lk.l_type=F_RDWR;

lk.l_whence=SEEK_SET;

lk.l_start=5;

lk.l_len=10;

//加锁

r=fcntl(fd,F_SETLK,&lk);

if(r==0)

printf(“加锁成功!\n”);

else

printf(“加锁失败!\n”);

while(1); //加个死循环为使进程不退出,程序退出后自动减锁

}

2. 获取锁的信息:

Getlock.c

#include<stdio.h>

#include<stdlib.h>

#include<unistd.h>

#include<fcntl.h>

void main()

{

int fd;

struct flock lk;

int r;

//打开文件

fd=open(“text.txt”,O_RDWR);

if(fd==0)

{

printf(“open error:%m\n”);

exit(-1);

}

//获取锁的信息:

r=fcntl(fd,F_GETLK,&lk);

if(r==0)

{

printf(“得到锁成功!\n”);

if(lk.l_type==F_RDWR)

{

printf(“写锁\n”);

}

}

else

{

printf(“得到锁失败!\n”);

}

}

结论:锁也是一个进程共享的信息

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值