Webserve(5): main函数

extern void addfd( int epollfd, int fd, bool one_shot );
extern void removefd( int epollfd, int fd );

在C和C++编程语言中,extern关键字用于声明一个变量或函数,表示其定义在另一个文件中。使用extern可以在多个文件之间共享变量或函数。extern的主要用途是声明一个在其他地方定义的全局变量或函数的引用,这对于跨文件访问和修改变量、调用函数特别有用。这种方式在大型项目中,特别是在需要将实现分散到多个文件中时,非常常见。

使用extern声明变量

当你在一个文件中声明一个带有extern的变量时,你告诉编译器这个变量的定义存在于程序的其他地方。这意味着存储空间不是在声明时分配的,而是在变量实际定义的地方分配。

例子

// File: main.c
extern int counter; // 告诉编译器变量counter在别处定义

int main() {
    counter = 1; // 使用变量
    return 0;
}

// File: counter.c
int counter; // 定义并分配存储空间

在这个例子中,counter变量在counter.c文件中定义,而在main.c文件中通过extern声明来引用。这允许main.c访问并修改counter.c中定义的counter变量。

使用extern声明函数

对于函数,使用extern是可选的,因为在C和C++中,函数默认就是外部链接的。即便如此,你仍然可以在声明外部函数时使用extern关键字,尽管这并不常见。

例子

// File: utils.c
void printMessage() {
    // 实现
}

// File: main.c
extern void printMessage(); // 可选的,因为函数默认是extern的

int main() {
    printMessage(); // 调用函数
    return 0;
}

在这个例子中,即使没有在main.c中显式地使用extern关键字,printMessage函数也是可以被外部访问的,因为函数在C/C++中默认具有外部链接。但是,明确地使用extern可以增强代码的可读性和意图表达。

void addsig(int sig, void( handler )(int)){
    struct sigaction sa;
    memset( &sa, '\0', sizeof( sa ) );
    sa.sa_handler = handler;
    sigfillset( &sa.sa_mask );
    assert( sigaction( sig, &sa, NULL ) != -1 );
}

这段代码是用于设置信号处理函数的。在UNIX或Linux系统编程中,信号处理是一种处理异步事件的机制。下面是对这段代码的详细解释:

void addsig(int sig, void( handler )(int)){

这一行定义了一个名为addsig的函数,它接受两个参数:一个是int sig,代表要处理的信号编号;另一个是函数指针void (*handler)(int),指向一个信号处理函数,这个函数接收一个int类型的参数(通常是信号的编号),返回类型为void

    struct sigaction sa;

定义了一个sigaction结构体变量sasigaction结构体用于指定信号的处理方式,包括信号处理函数、信号掩码和其他选项。

    memset( &sa, '\0', sizeof( sa ) );

使用memset函数初始化sa结构体,将其设置为0。这确保了结构体的所有成员都被清零,避免了未初始化的成员可能导致的不确定行为。

    sa.sa_handler = handler;

sa_handler成员设置为参数中提供的handler函数。sa_handler是一个函数指针,指向信号处理函数。当接收到sig指定的信号时,将执行handler函数。

    sigfillset( &sa.sa_mask );

sigfillset函数将sa.sa_mask信号集初始化,包括系统中所有的信号。这意味着在信号处理函数执行时,几乎所有的信号都将被阻塞,不会中断信号处理函数的执行。这是为了避免信号处理过程中发生的竞争条件。

    assert( sigaction( sig, &sa, NULL ) != -1 );

调用sigaction函数将sig信号的处理方式设置为sa指定的方式。如果sigaction调用成功,它会返回0;如果失败,返回-1。assert语句确保了sigaction调用成功。如果sigaction调用失败(即返回-1),assert将终止程序。

总结来说,这段代码的作用是为特定的信号sig注册一个新的处理函数handler,在信号处理期间阻塞其他信号,以确保信号处理的原子性和顺序性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值