C++ subprocesamiento múltiple 03 Expresión lambda y llamar una vez

1. Expresión lambda como entrada de hilo

La expresión Lambda (función anónima) es una de las características más importantes de C++ 11. Lambda proviene del concepto de programación funcional y también es una característica de los lenguajes de programación modernos.

Las ventajas son las siguientes:

Estilo de programación declarativo: defina la función de destino o el objeto de función de forma anónima en su lugar, que tiene una mejor legibilidad y capacidad de mantenimiento.
Conciso: no es necesario escribir una función adicional con nombre o un objeto de función, lo que evita la expansión del código y la dispersión de funciones.
Más flexible: implemente cierres funcionales cuando y donde los necesite.
Concepto y uso básico
La expresión lambda define una función anónima y puede capturar variables dentro de un cierto rango. La sintaxis es la siguiente:

[ capture ] ( params ) opt -> ret {
    
     body; };

1
capture: lista de captura
params: lista de parámetros
opt: opción de función
ret: tipo de valor de retorno
cuerpo: cuerpo de función
Una expresión lambda completa es la siguiente:

auto f = [](int a) -> int {
    
    return a + 1;};
cout << f(3) << endl;  //输出4

Versión detallada del enlace original: https://blog.csdn.net/luoyayun361/article/details/123491439

Defina un objeto de hilo directamente:

};
int main(int argc, char* argv[])
{
    
    
    thread th(
        [](int i) {
    
    cout << "test lmbda " << i << endl; },
        123
    );
    return 0;
}

inserte la descripción de la imagen aquí
[](int i) {cout << "test lmbda " << i << endl; Es equivalente a un puntero de función, que apunta a una función que imprime test lmbda i, el valor de i es copiado primero por el segundo parámetro , y luego pasó a esta función apuntada por el puntero

Usar un objeto como un hilo

class TestLambda
{
    
    
public:
    void Start()
    {
    
    
        thread th([this]() {
    
    cout << "name = " << name << endl; });
        th.join();
    }

    string name = "test lambda";
};
int main(int argc, char* argv[])
{
    
    
    TestLambda test;
    test.Start();
    return 0;
}

Cree un objeto primero, el objeto tiene un nombre de miembro
y luego llame al método de inicio de la clase. Este método envuelve una expresión Lambda en un subproceso y hace que el subproceso bloquee el subproceso principal. La expresión Lambda se usa como la entrada del subproceso , y la lista de captura captura el puntero this del objeto, indicando qué nombre de objeto imprimir
inserte la descripción de la imagen aquí

2. llame una vez a la función multiproceso, pero la función solo ingresa una vez

Por ejemplo, varios subprocesos necesitan inicializar una biblioteca, pero solo necesitan ingresarla una vez. Puede usar una variable global para juzgar. Una vez que un subproceso lo inicializa, configúrelo en falso, y otros subprocesos no podrán ingresar. La eficiencia es baja y afecta la legibilidad del código, por lo que se utiliza un nuevo método:

std::call_once():
El primer parámetro de esta función es un marcador y el segundo parámetro es un nombre de función.
Función: puede garantizar que la función func() se llame solo una vez cuando varios subprocesos la llamen. Tiene la capacidad de mutex, consume menos recursos que mutex y es más eficiente.
call_once() debe usarse junto con un indicador, que es std::once_flag ; donde once_flag es una estructura de datos, call_once() usa el indicador para determinar si la función se ejecuta. Después de que la llamada sea exitosa, configure el indicador a un estado llamado.

Así que ajuste la función que desea llamar solo una vez con call_once()

void SystemInit()
{
    
    
    cout << "Call SystemInit" << endl;
}

void SystemInitOne()
{
    
    
    static std::once_flag flag;
    std::call_once(flag, SystemInit);
}
int main(int argc, char* argv[])
{
    
    
    SystemInitOne();
    SystemInitOne();
    for (int i = 0; i < 3; i++)
    {
    
    
        thread th(SystemInitOne);
        th.detach();
    }
    getchar();
    return 0;
}

Se puede ver que aunque para poligonales tres tiempos, solo se llama una vez:
inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_42567607/article/details/125464750
Recomendado
Clasificación