Separar hilo

Hilo sin desacoplar

Cuando creamos un hilo con atributos predeterminados, el hilo se puede unir. Un subproceso que se puede unir debe usar pthread_join () en otro subproceso para esperar su finalización. Si un subproceso que se puede unir no usa pthread_join () para la operación después del final , el subproceso se convertirá en un "subproceso zombie". Cada hilo zombie consume algunos recursos del sistema. Cuando hay demasiados hilos zombie, la creación del hilo puede fallar .

Aquí hay un ejemplo de cómo crear un hilo zombie :

 

void* start_thread(void * arg) {
    //这个线程什么也不做,直接退出
    pthread_exit(NULL);
    return NULL;
}

int create_pthread(int n) {
    int try = 0;
    int i = 0;
    int err = 0;
    for(i = 0; i < n && try < 3; i++) {
        //当创建线程失败的时候,尝试3次
        pthread_t pt;
        err = pthread_create(&pt, NULL, start_thread, NULL);
        if(0 != err) {
            if(EAGAIN == err) {
                printf("errno : [EAGAIN]\n");
            }
            sleep(2);
            try ++;
        }
    }
    printf("create [%d] threads\n", i);

    return err;
}

int main(int argc, char * argv[]) {
    int n = 1 << 20;//最多创建 1M 个线程
    create_pthread(n);

    return 0;
}

El código anterior es la parte principal de la creación de un hilo zombie. Después de compilar y ejecutar el código anterior, cuál es el resultado de salida:

errno: [EAGAIN] 
errno: [EAGAIN] 
errno: [EAGAIN] 
crea hilos [32754]

 

En el ejemplo anterior, después de que comienza cada subproceso, no hace nada y termina inmediatamente. Finalmente, en mi entorno, solo se pueden crear 32,754 hilos adicionales.

Separar hilo

Cuando el subproceso se establece en el estado desconectado, cuando finaliza el subproceso, el sistema recuperará automáticamente sus recursos y ya no necesitará realizar la operación pthread_join () en otros subprocesos.

A continuación, realizamos algunas modificaciones al código, de modo que después de que cada subproceso comience la ejecución, el subproceso se separe y luego observe los resultados después de la ejecución.

void * start_thread (void * arg) { 
    // Tenga en cuenta que la operación de separación de hilos se realiza aquí. La separación de hilos también se puede hacer cuando se crea el hilo, 
    // Establecer 
    pthread_detach (pthread_self ()); 

    pthread_exit (NULL); 
    return NULL; 
} 

int create_pthread (int n) { 
    int try = 0; 
    int i = 0; 
    int err = 0; 
    for (i = 0; i <n && try <3; i ++) { 
        pthread_t pt; 
        err = pthread_create (& pt, NULL, start_thread, NULL); 
        if (0! = err) { 
            if (EAGAIN == err) { 
                printf ("errno: [EAGAIN] \ n"); 
            } 
            sleep (2); 
            try ++; 
        } 
    }
    printf ("crear [% d] hilos \ n", i); 

    volver err; 
} 

int main (int argc, char * argv []) { 
    int n = 1 << 20; 
    create_pthread (n); 

    devuelve 0; 
}

Los resultados son los siguientes:

crear [1048576] hilos

 

Como puede ver, los hilos 1M se crearon con éxito al final. Cuando no hay una operación pthread_join (), se crean un máximo de 32,754 hilos, porque no hay hilo separado. Después de su finalización, algunos de los recursos que le asigna el sistema todavía están ocupados y no se reciclan, lo que resulta en la imposibilidad de crear más Nuevo hilo. Después del hilo separado, sus recursos serán recuperados por el sistema y luego reutilizados. Por lo tanto, solo se pueden crear hilos 1M esta vez.

hilo después de unirse

En el manual man pthread_create, puede ver una descripción del estado desconectado y el estado de unión de un hilo. Dice que un subproceso está en un estado separado, de modo que después de que termine, el sistema recuperará los recursos; o está en un estado que se puede unir y está esperando pthread_join () en otro subproceso, y pthread_join () recuperará sus recursos.

Podemos hacer otro experimento. Después de crear un hilo que se puede unir, use pthread_join () para esperar su finalización, reclamar sus recursos y ver cuántos hilos se pueden crear como máximo.

void * start_thread (void * arg) { 

    pthread_exit (NULL); 
    devuelve NULL; 
} 

int create_pthread (int n) { 
    int try = 0; 
    int i = 0; 
    int err = 0; 
    para (i = 0; i <n && try <3; i ++) { 
        pthread_t pt; 
        err = pthread_create (& pt, NULL, start_thread, NULL); 
        if (0! = err) { 
            if (EAGAIN == err) { 
                printf ("errno: [EAGAIN] \ n"); 
            } 
            sueño (2); 
            prueba ++; 
        } 
        nulo * st = NULL; 
        // 这里 等待 一个 线程 的 结束 , 并 回收 其 资源
        err = pthread_join (pt, & st); 
        if (0! = err) {
            printf ("errno = [% d] \ n", err); 
            dormir (2); 
            prueba ++; 
        } 
    } 
    printf ("crear [% d] hilos \ n", i); 

    volver err; 
} 

int main (int argc, char * argv []) { 
    int n = 1 << 20; 
    create_pthread (n); 

    devuelve 0; 
}

 

Resultados de ejecución:

crear [1048576] hilos

 

Finalmente, se crearon 1M hilos.

La conclusión es que cuando escribimos una aplicación de subprocesos múltiples o establecemos el atributo de un subproceso en estado de separación, dejamos que el sistema reclame sus recursos; o estado que se puede unir, para que pueda usar pthread_join () para bloquear la espera de un subproceso Termina y recupera sus recursos, y pthread_join () también obtendrá el valor de retorno después de que el hilo salga para determinar el estado de salida del hilo.

115 artículos originales publicados · Me gusta 29 · Visitantes 50,000+

Supongo que te gusta

Origin blog.csdn.net/huabiaochen/article/details/100741460
Recomendado
Clasificación