首页 > 解决方案 > 从线程中停止 main

问题描述

我一直在我的 Raspberry pi 上修改 C,我的 main() 启动了几个线程,有一个小型网络服务器在其中一个线程中运行,

int main(){
        printf("hello world\n");
        thisfn();
        pthread_t tid, led_tid;
        int port = 9193;
        int rc = pthread_create(&tid, NULL, webserver, &port);
        assert (rc == 0);
/snip

如果网络服务器无法绑定到所需的端口,我希望整个程序停止。

void *webserver(void *vargp){
    int *port = (int *) vargp;
    printf("our port is %d\n", *port);

    /* First: Socket Creation */
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0){
            /* On error, -1 is returned */
            perror("Server Error!");
            abort();
    } else {
            printf("sockfd is %d\n", sockfd);
    }
    printf("Socket: sockfd: %d\n", sockfd);

    /* Second: Set socket options */
    int optval = 1;
    //int sockopt_int = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval, sizeof(optval) );
    int sockopt_int = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR , &optval, sizeof(optval) );
    if ( sockopt_int < 0 ){
            perror("Failed at setsockopt");
            abort();
    } else {
            printf("setsockopt succeeded\n");
    }

    /* Third: Bind to the port */
    /* int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); */
    struct sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(*port);

    int bind_int = bind(sockfd, (struct sockaddr *)&address, sizeof(address)) ;
    printf("bind_int ; %d\n", bind_int);
    if (bind_int < 0 ) {
            perror("Failed at bind");
            abort(); 
    } else {
            printf("bind succeeded\n");
    }

我一直在调用 abort(),我也尝试过 exit(1)、_exit(1) 等 - 但是,当我检查 valgrind 时,这样做会泄漏内存(~136 字节)。

==13052== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1
==13052==    at 0x4849CE0: calloc (vg_replace_malloc.c:711)
==13052==    by 0x401379B: allocate_dtv (dl-tls.c:322)
==13052==    by 0x40141D3: _dl_allocate_tls (dl-tls.c:539)
==13052==    by 0x489D9EF: allocate_stack (allocatestack.c:580)
==13052==    by 0x489D9EF: pthread_create@@GLIBC_2.4 (pthread_create.c:539)
==13052==    by 0x10EBF: main (fixmem.c:38)
==13052== 
==13052== LEAK SUMMARY:
==13052==    definitely lost: 0 bytes in 0 blocks
==13052==    indirectly lost: 0 bytes in 0 blocks
==13052==      possibly lost: 136 bytes in 1 blocks
==13052==    still reachable: 0 bytes in 0 blocks
==13052==         suppressed: 0 bytes in 0 blocks
==13052== 

我学到了一种思想,当东西撞到风扇时,退出就可以了,让操作系统清理之后。我试图用更快乐的 valgrind 让它退出/中止。我没有在这个函数中做任何明确的 mallocs/callocs 来在 abort() 之前调用 free() - 这带来了我的问题:

从线程停止主和退出的最干净的方法是什么?

谢谢!

标签: cpthreadsvalgrind

解决方案


如果网络服务器无法绑定到所需的端口,我希望整个程序停止。

如果你想让整个程序停止,调用它是完全可以的_exit()——这就是它的用途。

忽略 valgrind 报告的“泄漏”,它们是由于清理代码没有机会运行而造成的误报。由于操作系统回收了属于已退出进程的所有内存(和其他资源),因此实际上没有内存泄漏。


推荐阅读