调试freeradius时遇到的 线程池以及udp相关问题

调试线程池过程中遇到了一个return和pthread_exit 的问题;

google 一下发现右如下概念
首先,return 语句和 pthread_exit() 函数的含义不同,return 的含义是返回,它不仅可以用于线程执行的函数,普通函数也可以使用;pthread_exit() 函数的含义是线程退出,它专门用于结束某个线程的执行。

在主线程(main() 函数)中,return 和 pthread_exit() 函数的区别最明显。举个例子:

`#include <stdio.h>
#include <pthread.h>

void *ThreadFun(void *arg)
{
    sleep(5);//等待一段时间
    printf("http://c.biancheng.net\n");
}

int main()
{
    int res;
    pthread_t myThread;
    
    res = pthread_create(&myThread, NULL, ThreadFun, NULL);
    if (res != 0) {
        printf("线程创建失败");
        return 0;
    }
    printf("C语言中文网\n");
    return 0;
}`

编译、执行此程序,输出结果为:
C语言中文网
通过执行结果可以看到,主线程正常执行结束,myThread 线程并没有输出指定的数据。原因很简单,主线程执行速度很快,主线程最后执行的 return 语句不仅会终止主线程执行,还会终止其它子线程执行。也就是说,myThread 线程还没有执行输出语句就被终止了。

将上面程序中,main() 函数中的return 0;用如下语句替换:
pthread_exit(NULL);
重新编译、执行程序,运行结果为:

C语言中文网
http://c.biancheng.net

对比上面两个执行结果,可以得出的结论是:pthread_exit() 函数只会终止当前线程,不会影响其它线程的执行。
此外,pthread_exit() 函数还会自动调用线程清理程序(本质是一个由 pthread_cleanup_push() 指定的自定义函数),而 return 不具备这个能力。

实际场景中想终止某个子线程,强烈建议大家使用 pthread_exit() 函数。终止主线程时,return 和 pthread_exit() 函数发挥的功能不同,可以根据需要自行选择。

当然也可以使用pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。但是thread指定的线程必须是joinable的

udp 丢包

root@pingpong-radius-1 workspace]# cat /proc/net/snmp
------
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
Udp: 6956283 43197 177835 7255906 177835 0 0
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
UdpLite: 0 0 0 0 0 0 0

udp出现了RcvbufErrors 以及InErrors, 说明出现了系统UDP队列溢出时丢弃udp pkt。

网卡缓冲区溢出诊断

在Linux操作系统中,可以通过netstat -i –udp 命令来诊断网卡缓冲区是否溢出,RX-DRP列显示网卡丢失的数据包个数。

netstat  -i udp eth0
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0             1500 22099732      0      0 0      22572814      0      0      0 BMRU
lo              65536  3649897      0      0 0       3649897      0      0      0 LRU

操作系统内核缓冲区调优

运行命令sysctl -A | grep net | grep 'mem|backlog' | grep 'udp_mem|rmem_max|max_backlog'查看当前操作系统缓冲区的设置

net.core.netdev_max_backlog = 1000
net.core.rmem_max = 212992
net.ipv4.udp_mem = 90444        120595  180888
posted @ 2023-03-29 17:56  codestacklinuxer  阅读(26)  评论(0编辑  收藏  举报