CursosEmpresasBlogLiveConfPrecios

Traits, Metodos y Mutex para concurrencia

Clase 8 de 12 • Curso de Gestión de Servidores con Rust

Contenido del curso

Introducción

  • 1
    Qué aprenderemos

    Qué aprenderemos

    01:39 min
  • 2
    Ambiente de trabajo

    Ambiente de trabajo

    01:03 min

Protocolos TCP y HTTP

  • 3
    Conexión TCP

    Conexión TCP

    03:24 min
  • 4
    Conexión HTTP

    Conexión HTTP

    02:38 min
  • 5
    Validación de la respuesta en el servidor

    Validación de la respuesta en el servidor

    02:11 min

Concurrencia

  • 6
    Uso de concurrencia en Rust

    Uso de concurrencia en Rust

    01:34 min
  • 7
    Creación de hilos con Rust

    Creación de hilos con Rust

    02:19 min
  • 8
    Traits, Metodos y Mutex para concurrencia

    Traits, Metodos y Mutex para concurrencia

    Viendo ahora

Creación de un Servidor web multiprocesos

  • 9
    Mejora de nuestro servidor web con multitareas: ThreadPool

    Mejora de nuestro servidor web con multitareas: ThreadPool

    02:46 min
  • 10
    Configurando nuestro Threadpool

    Configurando nuestro Threadpool

    03:12 min

Limpieza del servidor

  • 11
    Uso de Drop

    Uso de Drop

    01:18 min

Hacerlo de la manera fácil

  • 12
    Uso de frameworks y crates

    Uso de frameworks y crates

    02:02 min
Tomar examen

Escuelas

  • Desarrollo Web
    • Fundamentos del Desarrollo Web Profesional
    • Diseño y Desarrollo Frontend
    • Desarrollo Frontend con JavaScript
    • Desarrollo Frontend con Vue.js
    • Desarrollo Frontend con Angular
    • Desarrollo Frontend con React.js
    • Desarrollo Backend con Node.js
    • Desarrollo Backend con Python
    • Desarrollo Backend con Java
    • Desarrollo Backend con PHP
    • Desarrollo Backend con Ruby
    • Bases de Datos para Web
    • Seguridad Web & API
    • Testing Automatizado y QA para Web
    • Arquitecturas Web Modernas y Escalabilidad
    • DevOps y Cloud para Desarrolladores Web
  • English Academy
    • Inglés Básico A1
    • Inglés Básico A2
    • Inglés Intermedio B1
    • Inglés Intermedio Alto B2
    • Inglés Avanzado C1
    • Inglés para Propósitos Específicos
    • Inglés de Negocios
  • Marketing Digital
    • Fundamentos de Marketing Digital
    • Marketing de Contenidos y Redacción Persuasiva
    • SEO y Posicionamiento Web
    • Social Media Marketing y Community Management
    • Publicidad Digital y Paid Media
    • Analítica Digital y Optimización (CRO)
    • Estrategia de Marketing y Growth
    • Marketing de Marca y Comunicación Estratégica
    • Marketing para E-commerce
    • Marketing B2B
    • Inteligencia Artificial Aplicada al Marketing
    • Automatización del Marketing
    • Marca Personal y Marketing Freelance
    • Ventas y Experiencia del Cliente
    • Creación de Contenido para Redes Sociales
  • Inteligencia Artificial y Data Science
    • Fundamentos de Data Science y AI
    • Análisis y Visualización de Datos
    • Machine Learning y Deep Learning
    • Data Engineer
    • Inteligencia Artificial para la Productividad
    • Desarrollo de Aplicaciones con IA
    • AI Software Engineer
  • Ciberseguridad
    • Fundamentos de Ciberseguridad
    • Hacking Ético y Pentesting (Red Team)
    • Análisis de Malware e Ingeniería Forense
    • Seguridad Defensiva y Cumplimiento (Blue Team)
    • Ciberseguridad Estratégica
  • Liderazgo y Habilidades Blandas
    • Fundamentos de Habilidades Profesionales
    • Liderazgo y Gestión de Equipos
    • Comunicación Avanzada y Oratoria
    • Negociación y Resolución de Conflictos
    • Inteligencia Emocional y Autogestión
    • Productividad y Herramientas Digitales
    • Gestión de Proyectos y Metodologías Ágiles
    • Desarrollo de Carrera y Marca Personal
    • Diversidad, Inclusión y Entorno Laboral Saludable
    • Filosofía y Estrategia para Líderes
  • Diseño de Producto y UX
    • Fundamentos de Diseño UX/UI
    • Investigación de Usuarios (UX Research)
    • Arquitectura de Información y Usabilidad
    • Diseño de Interfaces y Prototipado (UI Design)
    • Sistemas de Diseño y DesignOps
    • Redacción UX (UX Writing)
    • Creatividad e Innovación en Diseño
    • Diseño Accesible e Inclusivo
    • Diseño Asistido por Inteligencia Artificial
    • Gestión de Producto y Liderazgo en Diseño
    • Diseño de Interacciones Emergentes (VUI/VR)
    • Desarrollo Web para Diseñadores
    • Diseño y Prototipado No-Code
  • Contenido Audiovisual
    • Fundamentos de Producción Audiovisual
    • Producción de Video para Plataformas Digitales
    • Producción de Audio y Podcast
    • Fotografía y Diseño Gráfico para Contenido Digital
    • Motion Graphics y Animación
    • Contenido Interactivo y Realidad Aumentada
    • Estrategia, Marketing y Monetización de Contenidos
  • Desarrollo Móvil
    • Fundamentos de Desarrollo Móvil
    • Desarrollo Nativo Android con Kotlin
    • Desarrollo Nativo iOS con Swift
    • Desarrollo Multiplataforma con React Native
    • Desarrollo Multiplataforma con Flutter
    • Arquitectura y Patrones de Diseño Móvil
    • Integración de APIs y Persistencia Móvil
    • Testing y Despliegue en Móvil
    • Diseño UX/UI para Móviles
  • Diseño Gráfico y Arte Digital
    • Fundamentos del Diseño Gráfico y Digital
    • Diseño de Identidad Visual y Branding
    • Ilustración Digital y Arte Conceptual
    • Diseño Editorial y de Empaques
    • Motion Graphics y Animación 3D
    • Diseño Gráfico Asistido por Inteligencia Artificial
    • Creatividad e Innovación en Diseño
  • Programación
    • Fundamentos de Programación e Ingeniería de Software
    • Herramientas de IA para el trabajo
    • Matemáticas para Programación
    • Programación con Python
    • Programación con JavaScript
    • Programación con TypeScript
    • Programación Orientada a Objetos con Java
    • Desarrollo con C# y .NET
    • Programación con PHP
    • Programación con Go y Rust
    • Programación Móvil con Swift y Kotlin
    • Programación con C y C++
    • Administración Básica de Servidores Linux
  • Negocios
    • Fundamentos de Negocios y Emprendimiento
    • Estrategia y Crecimiento Empresarial
    • Finanzas Personales y Corporativas
    • Inversión en Mercados Financieros
    • Ventas, CRM y Experiencia del Cliente
    • Operaciones, Logística y E-commerce
    • Gestión de Proyectos y Metodologías Ágiles
    • Aspectos Legales y Cumplimiento
    • Habilidades Directivas y Crecimiento Profesional
    • Diversidad e Inclusión en el Entorno Laboral
    • Herramientas Digitales y Automatización para Negocios
  • Blockchain y Web3
    • Fundamentos de Blockchain y Web3
    • Desarrollo de Smart Contracts y dApps
    • Finanzas Descentralizadas (DeFi)
    • NFTs y Economía de Creadores
    • Seguridad Blockchain
    • Ecosistemas Blockchain Alternativos (No-EVM)
    • Producto, Marketing y Legal en Web3
  • Recursos Humanos
    • Fundamentos y Cultura Organizacional en RRHH
    • Atracción y Selección de Talento
    • Cultura y Employee Experience
    • Gestión y Desarrollo de Talento
    • Desarrollo y Evaluación de Liderazgo
    • Diversidad, Equidad e Inclusión
    • AI y Automatización en Recursos Humanos
    • Tecnología y Automatización en RRHH
  • Finanzas e Inversiones
    • Fundamentos de Finanzas Personales y Corporativas
    • Análisis y Valoración Financiera
    • Inversión y Mercados de Capitales
    • Finanzas Descentralizadas (DeFi) y Criptoactivos
    • Finanzas y Estrategia para Startups
    • Inteligencia Artificial Aplicada a Finanzas
    • Domina Excel
    • Financial Analyst
    • Conseguir trabajo en Finanzas e Inversiones
  • Startups
    • Fundamentos y Validación de Ideas
    • Estrategia de Negocio y Product-Market Fit
    • Desarrollo de Producto y Operaciones Lean
    • Finanzas, Legal y Fundraising
    • Marketing, Ventas y Growth para Startups
    • Cultura, Talento y Liderazgo
    • Finanzas y Operaciones en Ecommerce
    • Startups Web3 y Blockchain
    • Startups con Impacto Social
    • Expansión y Ecosistema Startup
  • Cloud Computing y DevOps
    • Fundamentos de Cloud y DevOps
    • Administración de Servidores Linux
    • Contenerización y Orquestación
    • Infraestructura como Código (IaC) y CI/CD
    • Amazon Web Services
    • Microsoft Azure
    • Serverless y Observabilidad
    • Certificaciones Cloud (Preparación)
    • Plataforma Cloud GCP

Platzi y comunidad

  • Platzi Business
  • Live Classes
  • Lanzamientos
  • Executive Program
  • Trabaja con nosotros
  • Podcast

Recursos

  • Manual de Marca

Soporte

  • Preguntas Frecuentes
  • Contáctanos

Legal

  • Términos y Condiciones
  • Privacidad
  • Tyc promociones
Reconocimientos
Reconocimientos
Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
Logo reconocimientoPrimera Startup EdTech · 2018
Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
Logo reconocimientoCEO Mejor Emprendedor del año · 2024
De LATAM conpara el mundo
YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads

      Una herramienta importante que Rust tiene para lograr la concurrencia de envío de mensajes es el channel, un concepto de programación que contiene la biblioteca estándar de Rust.

      Rust pretende ser un lenguaje con muy buen soporte para la concurrencia; y tiene tres partes: ownership & lifetimes, los traits Send y Sync, y Mutex.

      Channel


      Trabajaremos en un programa que tiene un hilo para generar valores y enviarlos por un canal, y otro hilo que recibirá los valores y los imprimirá. Enviaremos valores simples entre hilos usando un canal para ilustrar la función.

      use std::sync::mpsc; use std::thread; use std::time::Duration; fn main() { let (tx, rx) = mpsc::channel(); let tx1 = mpsc::Sender::clone(&tx); thread::spawn(move || { let vals = vec![ String::from("hola"), String::from("desde"), String::from("el"), String::from("hilo 1"), ]; for val in vals { tx1.send(val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); thread::spawn(move || { let vals = vec![ String::from("vemos"), String::from("como "), String::from("trabaja"), String::from("hilo 2"), ]; for val in vals { tx.send(val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); for received in rx { println!("Obetener mensaje {}", received); } }

      Ejecutar

      Analicemos un poco lo que hacemos:

      use std::sync::mpsc;

      Crea un nuevo canal asincrónico, devolviendo las mitades del transmisor / receptor. Todos los datos enviados en el remitente estarán disponibles en el receptor en el mismo orden en que fueron enviados, y ningún envío bloqueará el hilo de llamada. Aquí tx funcionará como transmisor de datos y rx como receptor.

      let (tx, rx) = mpsc::channel();

      Vamos mpsca usar y expandir el código, esta vez, antes de crear el primer hilo generado, llamamos clone al extremo emisor del canal. Esto nos dará un nuevo controlador de envío que podemos pasar al primer subproceso generado. Pasamos el extremo del envío original del canal a un segundo hilo generado. Esto nos da dos hilos, cada uno enviando mensajes diferentes al extremo receptor del canal.

      let tx1 = mpsc::Sender::clone(&tx);

      Eso logrará que tengamos una salida similar a esta:

      Send & Sync


      Los traits SendySync capturan y controlan las dos formas más comunes en las que se accede a un dato y se lo arroja a los hilos, dictando si es seguro transferir la propiedad o pasar una referencia a otro hilo.

      Los traits son “marker traits”, lo que significa que no tienen métodos y no proporcionan inherentemente ninguna funcionalidad, solo son útiles para hacer cumplir invariantes relacionados con la concurrencia.

      Con Send, indica que la propiedad del tipo que implementa el envío se puede transferir entre subprocesos.

      El segundo de estos traits es llamado Sync. le indica al compilador que algo de este tipo no tiene posibilidad de introducir inseguridad en memoria cuando es usado de manera concurrente por múltiples hilos de ejecución.

      Mutex


      Para permitir que los hilos muten datos compartidos, necesitamos un tipo que pueda forzar el acceso mutuo exclusivo a los datos compartidos en tiempo de ejecución. La biblioteca estándar de Rust proporciona std :: sync :: Mutex <T> para este propósito.

      Mutex es una abreviatura de exclusión mutua , ya que, en un mutex, solo un hilo puede acceder a algunos datos en un momento dado. Para acceder a los datos en un mutex, un subproceso primero debe indicar que desea acceder al solicitar la adquisición del bloqueo del mutex . El bloqueo es una estructura de datos que forma parte del mutex que realiza un seguimiento de quién tiene actualmente acceso exclusivo a los datos.

      Los mutexes tienen fama de ser difíciles de usar porque debes recordar dos reglas:

      1. Debe intentar adquirir el bloqueo antes de usar los datos.
      2. Cuando haya terminado con los datos que guarda el mutex, debe desbloquear los datos para que otros hilos puedan adquirir el bloqueo.

      Lo sé, hablar de concurrencia es un tema muy complicado, pero practicando lo dominarás. En esta clase tratamos de ver los traits, bibliotecas y métodos, que pueden ayudarnos a tener una mejor concurrencia dentro de nuestro programa.

      Me gustaría saber cómo te sentiste con esta lección, en los comentarios cuéntame qué problemas has tenido cuando aprendes concurrencia en diferentes lenguajes de programación.

      Comentarios

        Frank Moreno

        Frank Moreno

        student•
        hace 5 años

        Otra forma de clonar es la siguiente:

        let tx1 = tx.clone();
        Osvaldo Frias

        Osvaldo Frias

        student•
        hace 5 años

        La primera parte de la explicación en el tema de Channel fue muy clara más con los ejemplos.

        Por otro lado, me cuestra trabajo imaginar el uso de los traits y mutex sin un ejemplo o aplicación clara. Se puede entender el concepto, pero nada más allá.

          Angel Fernando Quiroz Campos

          Angel Fernando Quiroz Campos

          student•
          hace 5 años

          Los traits en Rust se comportan más como interface en otros lenguajes

        Gerardo Alberto Soto Alvarez del Castillo

        Gerardo Alberto Soto Alvarez del Castillo

        student•
        hace 5 años

        Mi resumen para el uso de Mutex:

        ++Utilizamos Mutex cuando hay más de un thread (hilos - procesos) que va a consumir (modificar) una variable,++ y para evitar que 2 o más threads (hilos - procesos) accedan al mismo tiempo y modifiquen el valor de la variable, Mutex crea una estructura que permite bloquear el acceso a una variable MIANTRAS es utilizada por un thread (hilo - proceso), ++esto garantiza la seguridad de los datos haciendo un proceso atómico, pero disminuye el performace (la velocidad) de ejecución (Supongo por que ya no habría paralelismo, en cambio, el proceso será en serie).++

        Ejemplo:

        use std::sync::{Mutex, Arc}; use std::thread; //use std::rc::Rc; // Rc no soporta el bloqueo de variables. Utilizamos: Arc fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![]; for _ in 0..10 { //Multiple Ownership with Multiple Threads: let counter let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap();// bloqueo de la var: counter *num += 1; }); handles.push(handle); } for handle in handles { handle.join().unwrap();// join all processes created and wait // to finish them. } println!("Result: {}", *counter.lock().unwrap()); }

        Salida: Result: 10

        Sin el bloqueo de variables (Arc, lock()), el resultado podría ser: 9, 7 ó 6, o hasta 10, dependería del multi-procesador y el tiempo de ejecución de cada Thread.

        Gerardo Alberto Soto Alvarez del Castillo

        Gerardo Alberto Soto Alvarez del Castillo

        student•
        hace 5 años

        ++Cuando utilizar Send++

        Permitir la transferencia de propiedad entre hilos con Send El marcador Send ++indica que la propiedad del tipo que implementa Send puede ser transferida entre hilos.++ Casi todos los tipos en Rust son Send, pero ++hay algunas excepciones, incluyendo Rc<T>:++ este ++no puede ser Send++ porque si se clona un valor Rc<T> y se intenta transferir la propiedad del clon a otro hilo, ++ambos hilos podrían actualizar la cuenta de referencias al mismo tiempo.++ Por esta razón, ++Rc<T> está implementado para su uso en situaciones de un solo hilo++ en las que ++no se quiere pagar++ la penalización de ++rendimiento de la seguridad++ de los hilos.

        Por lo tanto, el sistema de tipos en Rust y los límites de los rasgos ++aseguran que nunca puedas enviar accidentalmente un valor Rc<T> a través de hilos de forma insegura.++ Cuando intentamos hacer esto, obtenemos el error de que el trait Send no está implementado para Rc<Mutex<i32>>. Cuando cambiamos a Arc<T>, que es Send, el código compila.

        Cualquier tipo compuesto enteramente por tipos Send se marca automáticamente como Send también. ++Casi todos los tipos primitivos son Send,++ aparte de los punteros crudos, que discutiremos en el Capítulo 19.

        Fuente: https://doc.rust-lang.org/book/ch16-04-extensible-concurrency-sync-and-send.html#allowing-transference-of-ownership-between-threads-with-send

        Gerardo Alberto Soto Alvarez del Castillo

        Gerardo Alberto Soto Alvarez del Castillo

        student•
        hace 5 años

        mmm... falto la imagen del punto:

        let tx1 = mpsc::Sender::clone(&tx);

        Eso logrará que tengamos una salida similar a esta:

        (Mi salida): Mensaje obtenido: hilo1-1:Hola, Mensaje obtenido: hilo2-1:Vemos Mensaje obtenido: hilo1-2:desde Mensaje obtenido: hilo2-2:como Mensaje obtenido: hilo1-3:el Mensaje obtenido: hilo2-3:trabaja Mensaje obtenido: hilo1-4:hilo 1 Mensaje obtenido: hilo2-4:el hilo 2

        Gerardo Alberto Soto Alvarez del Castillo

        Gerardo Alberto Soto Alvarez del Castillo

        student•
        hace 5 años

        Otro ejemplo para entender el uso del mpsc y channel() - (Que se puede analizar como una arquitectura cliente/servidor):

        use std::sync::mpsc; use std::thread; fn main() { let (tx, rx) = mpsc::channel(); thread::spawn(move || { let val = String::from("hi"); tx.send(val).unwrap(); }); let received = rx.recv().unwrap(); println!("Got: {}", received); }``` Fuente: https://doc.rust-lang.org/book/ch16-02-message-passing.html