Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: C# - Semafori in .net

  1. #1

    C# - Semafori in .net

    Ciao a tutti! mi sono trovato a dover affrontare questa problematica... Spiego brevemente:
    sono in un ciclo di gioco, e ho bisogno di far girare delle sequenze di filmati. Ho trovato il modo di gestirle ottimalmente con la classe Semaphore, ma appena ho creato più di 2 thread la sitazione è diventata fastidiosa... Come scritto nella MSDN il semaforo non esegue thread con una sequenza, va a caso! Però ho bisogno di una sequenza... Come faccio?
    Premetto che mi serve un semaforo perchè devo gestire più thread... E mi servono i thread perchè mi serve captare l'input del joystick!

    Questo è lo scheletro del codice. Grazie in anticipo


    public static Semaphore Semaforo = new Semaphore(0, 1);


    public static void Scena1()
    {
    Thread t1=new Thread(new ThreadStart(Frame1));
    t1.Start();

    Thread t2 = new Thread(new ThreadStart(Frame2));
    t2.Start();

    Thread t3 = new Thread(new ThreadStart(Frame3));
    t3.Start();

    Thread t4 = new Thread(new ThreadStart(Frame4));
    t4.Start();

    Semaforo.Release(1);

    }

    public static void Frame1()
    {
    Semaforo.WaitOne();
    //codice
    Semaforo.Release();
    }
    public static void Frame2()
    {
    Semaforo.WaitOne();
    //codice
    Semaforo.Release();
    }
    public static void Frame3()
    {
    Semaforo.WaitOne();
    //codice
    Semaforo.Release();
    }
    public static void Frame4()
    {
    Semaforo.WaitOne();
    //codice
    Semaforo.Release();
    }

  2. #2
    mmm niente eh?

  3. #3
    Ciao.
    Se ti serve gestire una sequenza ... lo puoi fare con dei flag.
    Tempo fa avevo fatto qualcosa.
    Per esempio al termine del Thread1 metti a True un flag, il quale, permette l'esecuzione del thread2 .... al termine del thread2, stessa cosa per il thread3.
    Esempio:

    codice:
    Private Thread1End as boolean
    Private Thread2End as boolean
    
    Private sub Frame1
    .....
    Thread1End=true
    End Sub
    
    private sub Frame2
    Wait:
    if not thread1end then
    goto Wait
    end if
    
    ......
    
    thread2end=true
    end sub
    non so se sia la soluzione corretta .... ma potrebbe essere un punto di partenza.

    Facci sapere...
    Ciao

  4. #4
    si ho fatto una roba simile... ma con un contatore di stato.. però avevo usato questo codice

    public static void Frame1()
    {
    Semaforo.WaitOne();

    if(ActiveThread!=1)
    {
    return;
    }

    Semaforo.Release();
    }


    sì, la sequenza così viene seguita... ma quel "return" fa effettivamente spegnere il thread... il problema è che poi non ci ritorna più dentro! Forse ho sbagliato qualcosa?

  5. #5
    Ooops, per un attimo mi sono dimenticato che ti serviva in c#, ad ogni modo il concetto lo hai capito.

    Con return, termini l'esecuzione del thread, invece tu, lo devi tenere in attesa quindi, dovresti fare un goto come ho fatto io nell'esempio.
    Oppure lavori nella routine Scena1 ed in base al valore del contatore, fai partire il thread corrispondente all'indice di un oggetto List(of Thread).

    Facci sapere...
    Ciao

  6. #6
    grandissimo! Ho trovato il modo! Per chi avesse il mio stesso problema:

    public static void Scena1()
    {
    ActiveFrame=1;

    Thread t1=new Thread(new ThreadStart(Frame1));
    t1.Start();

    Thread t2 = new Thread(new ThreadStart(Frame2));
    t2.Start();

    Thread t3 = new Thread(new ThreadStart(Frame3));
    t3.Start();

    Thread t4 = new Thread(new ThreadStart(Frame4));
    t4.Start();

    Semaforo.Release(1);

    }
    public static int ActiveFrame;
    public static void Frame1()
    {
    Inizio:
    Semaforo.WaitOne();
    if(ActiveFrame!=1)
    {
    Semaforo.Release();
    goto Inizio;
    }
    //codice
    ActiveFrame=2;
    Semaforo.Release();
    }
    public static void Frame2()
    {
    Inizio:
    Semaforo.WaitOne();
    if(ActiveFrame!=1)
    {
    Semaforo.Release();
    goto Inizio;
    }
    //codice
    ActiveFrame=3;
    Semaforo.Release();
    }
    public static void Frame3()
    {
    Inizio:
    Semaforo.WaitOne();
    if(ActiveFrame!=3)
    {
    Semaforo.Release();
    goto Inizio;
    }
    //codice
    ActiveFrame=4;
    Semaforo.Release();
    }
    public static void Frame4()
    {
    Inizio:
    Semaforo.WaitOne();
    if(ActiveFrame!=4)
    {
    Semaforo.Release();
    goto Inizio;
    }
    //codice
    ActiveFrame=-1;
    Semaforo.Release();
    }

  7. #7
    mmmhhh .... avevo pensato ad una cosa più tipo così:
    codice:
     public partial class Form1 : Form
        {
            List<System.Threading.Thread> Threads;
            private Int32 Contatore = 0;
    
            public Form1()
            {
                InitializeComponent();
            }
    
         
    
            private void button1_Click(object sender, EventArgs e)
            {
                System.Threading.Thread t1 = new System.Threading.Thread(new System.Threading.ThreadStart(StartThreads));
                t1.Start();
                        }
    
            public void StartThreads()
            {
                Threads = new List<System.Threading.Thread>();
                Threads.Add(new System.Threading.Thread(new System.Threading.ThreadStart(Frame1)));
                Threads.Add(new System.Threading.Thread(new System.Threading.ThreadStart(Frame2)));
                Threads.Add(new System.Threading.Thread(new System.Threading.ThreadStart(Frame3)));
                Threads.Add(new System.Threading.Thread(new System.Threading.ThreadStart(Frame4)));
    
                while (true)
                {
                    if (Contatore == Threads.Count)
                    {
                        MessageBox.Show("Tutti i Thread Eseguiti");
                        return;
                    }
                    if (Threads[Contatore].IsAlive != true)
                    {
                        Threads[Contatore].Start();
                    }
                }
            }
    
    
            public  void Frame1()
            {
                MessageBox.Show("Thread1 Started");
                Contatore += 1;
           }
            public  void Frame2()
            {
                MessageBox.Show("Thread2 Started");
                Contatore += 1;
            }
            public  void Frame3()
            {
                MessageBox.Show("Thread3 Started");
                Contatore += 1;
            }
            public  void Frame4()
            {
                MessageBox.Show("Thread4 Started");
                Contatore += 1;
            }
    
        }

    Ciao!!

  8. #8
    Si in effetti se mi fossero bastati i thread sarebbe stata la soluzione più corretta... ma siccome lavoro con le SDL, le risorse come la Video.Surface vengono usate da più thread contemporaneamente, in lettura e in scrittura... e ciò causa un crash del programma in quanto i thread si incastrano... invece il semaforo risolve tutti i problemi, l'unico problema era la sequenza dei thread ma l'ho risolta nel post precedente grazie

  9. #9
    Utente di HTML.it L'avatar di Stoicenko
    Registrato dal
    Feb 2004
    Messaggi
    2,254
    assolutamente non usare Goto in c#, ma neanche fattelo passare per la testa!!!!

    per i semafori in c# esiste la classe Mutex o al limite se vuoi usare contatori usali dichiarati così:

    codice:
    private volatile Int32 contatore;
    e per usarli usa blocchi loccati sennò non hai percezione del reale valore del contatore (più thread potrebbero modificarlo assieme)

  10. #10
    aspe aspe! XD andiamo piano...
    allora.
    1)
    sono andato a vedere le referenze sui tipi "volatile" e ho visto questo: "La parola chiave volatile indica che un campo potrebbe essere modificato da più thread eseguiti contemporaneamente"

    e ok questa è una sicurezza in più. Grazie

    2)
    Qual'è il problema con i GoTo in c#?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.