Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

223
Vistas
¿SemaphoreSlim (1, 1) garantiza que las lecturas y las escrituras se eliminen de los cachés como el bloqueo?

Pregunta adicional

¿ SemaphoreSlim(1, 1) aún garantiza que tengo la salida correcta 1000000, incluso si task1 y task2 se ejecutan en 2 núcleos diferentes?

pregunta original

Teniendo en cuenta el siguiente fragmento de código, ¿el _semaphore tiene el mismo efecto que lock ?

Las salidas:

  1. usando bloqueo: 1000000
  2. _semaphore = new SemaphoreSlim(1, 1) : 1000000 (Ejecuto el programa 10 veces y los resultados son los mismos)
  3. _semaphore = new SemaphoreSlim(10, 10) : varía de 999998 a 999990 a 1000000, etc.
 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ConsoleApp1 { class Calculate { private int _val = 0; private object _addLock = new object(); private SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); public int Val { get { return _val; } } public void IncreManyTimes() { for (int i = 0; i < 500000; ++i) { //lock(_addLock) //{ // _val = _val + 1; //} _semaphore.Wait(); _val = _val + 1; _semaphore.Release(); } } } class Program { static void Main(string[] args) { Calculate calculate = new Calculate(); Task.Run(() => { Task task1 = Task.Run(() => { calculate.IncreManyTimes(); }); Task task2 = Task.Run(() => { calculate.IncreManyTimes(); }); Task.WaitAll(task1, task2); }).Wait(); Console.WriteLine(calculate.Val); Console.ReadKey(); } } }

La pregunta relacionada: ¿El bloqueo garantiza que las lecturas y escrituras se eliminen de los cachés? ¿Si es así, cómo?

Y mi pregunta podría describirse como: ¿ SemaphoreSlim(1, 1) garantiza que las lecturas y escrituras se eliminen de los cachés?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Los parámetros en semaphoreslim especifican cuántos subprocesos pueden operar simultáneamente y cuál es el conteo inicial. Si desea utilizar semaphoreslim como el equivalente de la declaración de bloqueo de c#, entonces la cantidad de subprocesos admitidos debe ser uno. Cuando inicializa su sempahore con 10, está diciendo que se pueden ejecutar hasta 10 subprocesos al mismo tiempo, lo que no es lo mismo que un bloqueo.

El semáforo no tiene nada que ver con el lavado de lecturas o escrituras, ya que se basa completamente en cómo usa el semáforo.

Si lo va a usar como bloqueo, debe asegurarse de que cada vez que se espera el semáforo, también se libera, así que use un bloque try/finally.

over 4 years ago · Santiago Trujillo Denunciar

0

¿El _semaphore tiene el mismo efecto que el lock ?

Si y no. Teniendo en cuenta el comportamiento de su método IncreManyTimes , tiene el mismo efecto ( _val = _val + 1; no se ejecutará simultáneamente por varios subprocesos).

Aunque tienen algunas diferencias. Por ejemplo, el lock siempre está dedicado a su subproceso de ejecución, mientras que SemaphoreSlim se puede liberar desde cualquier subproceso. Es por eso que un SemaphoreSlim es una buena alternativa para 'bloquear' un bloque de código que contiene una await (que ni siquiera se compilaría con lock porque no funcionaría según lo previsto si la continuación se ejecuta en un subproceso diferente).

Como nota adicional, si hay una excepción dentro del lock , el candado se libera. Para lograr el mismo efecto debes poner tu _semaphore.Release(); en un bloque finally .

Además, SemaphorSlim es un objeto desechable, por lo que debería considerar implementar IDisposable en su clase Calculate .

Y finalmente, no sé si esto es solo un ejemplo simplificado, pero aquí no necesita ninguno de esos. Puede incrementar simplemente Interlocked.Increment(ref _val) , que no necesita bloqueo.

Editar:

¿ SemaphoreSlim(1, 1) aún garantiza que tengo la salida correcta 1000000, incluso si task1 y task2 se ejecutan en 2 núcleos de CPU diferentes?

Sí, porque solo permite un hilo en la sección crítica a la vez.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda