Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    142

    [C] socket multi-thread

    ciao a tutti, di solito su questo forum riesco a trovare sempre una risposta ai miei problemi.. speriamo che anche questa volta sia così..

    sto creando un server multi-thread.

    Codice PHP:
        while (1) {
            if ( (
    fd2 accept(fd1, (struct sockaddr*) &client_addr, &client_len)) <= )
                
    write(2"Errore Accept\n"strlen("Errore Accept\n"));
            else {
          
    sprintf(buf"FD2= %d\n"fd2);
            
    write(2bufstrlen(buf) );
                if (
    pthread_create(&tidNULLclient, &fd2))
        
    write(2"Errore pthread_create\n"strlen("Errore pthread_create\n"));
                else {
                    
    sprintf(buf"#Connessione: %d; Thread client: %u; Numero client connessi: %d#\n"fd2, (unsigned int)tidCONT 1);
                    
    write(1bufstrlen(buf));
                    
                    
                }
            }
            
    sleep(1);
        }

      
    close(fd1);

    questa parte di codice è quella che crea il thread nuovo...il problema che ho è che il canale di comunicazione fd2 cambia di valore prima che il thread ne abbia preso il valore, per risolvere (artigianalmente) ho inserito quello sleep(1) che ovviamente è bruttissimo da vedere.

    come posso risolvere in maniera corretta?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Crea un semaforo dopo la accept e mettiti in attesa dopo la creazione del thread.

    All'interno del nuovo thread, preleva il valore passato e segnala il semaforo.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    142
    mi faresti un esempio?

    grazie

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da atomico
    mi faresti un esempio?
    Ero praticamente sicuro che avresti fatto questa domanda ...

    Hai provato a cercare/studiare/scrivere qualcosa tu? Sinceramente ho solo risposto per darti una strada da seguire, non per scrivere codice ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2005
    Messaggi
    142
    ho fatto così e sembra funzionare.. mi puoi dire almeno se è corretto?
    Codice PHP:

    while (1) {
        
            if ( (
    fd2 accept(fd1, (struct sockaddr*) &client_addr, &client_len)) <= )
                
    write(2"Errore Accept\n"strlen("Errore Accept\n"));
            else {
          
          
    sprintf(buf"FD2= %d\n"fd2);
            
    write(2bufstrlen(buf) );
                if (
    pthread_create(&tidNULLclient, &fd2))
        
    write(2"Errore pthread_create\n"strlen("Errore pthread_create\n"));
                else {
                    
    sprintf(buf"#Connessione: %d; Thread client: %u; Numero client connessi: %d#\n"fd2, (unsigned int)tidCONT 1);
                    
    write(1bufstrlen(buf));
                
                
    pthread_cond_wait(&cond, &sem);    
                    
                }
            } 
    e nella funziona dopo l'acquisizione ho inserito

    pthread_cond_signal(&cond);

  6. #6
    Originariamente inviato da atomico
    Codice PHP:
                if (pthread_create(&tidNULLclient, &fd2)) 
    stai passando l'indirizzo di una variabile (fd2) ad un thread (il che significa... guai) ;-)

    io preferirei passargli un puntatore ad una struttura allocata dinamicamente con dentro tutti i parametri di cui necessitano ogni thread.

    Se proprio vuoi passargli un intero, allora puoi barare, castando l'intero a void * e poi ri-castando (dentro il thread) il void * all'intero, ma... non è portabile.

    Eccoti un esempio (giusto per non fargli fare nulla, ad ogni thread faccio calcolare il numero di fibonacci in modo lento/ricorsivo):
    Codice PHP:
    /*
    13 june 2010, MacApp

    Simple example in C, using pthread

    $ gcc --version
    i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)
    $ gcc -Wall -Wextra -ansi -pedantic main.c

    */

    #include <pthread.h>
    #include <stdio.h>
    #include <assert.h>
    #include <stdlib.h>

    typedef unsigned long MyNatural;

    typedef struct{
        
    MyNatural fArg;
    SMyThreadArg;

    static 
    MyNatural IGSlowRecursiveFibonacci (const MyNatural theNatural){
        
    MyNatural ret 1;
        
    assert (theNatural 0);
        if (
    theNatural 2){
            
    ret IGSlowRecursiveFibonacci (theNatural 1) + IGSlowRecursiveFibonacci (theNatural 2);
        }
        return 
    ret;
    }

    static 
    void MyThreadWorkerWithStruct (void theThreadArg){
        
    SMyThreadArg aThreadArg = (SMyThreadArg *) theThreadArg;
        
    assert (NULL != theThreadArg);
        
    printf ("%s: IGRecursiveFibonacci (%ld) = %ld;\n"__func__aThreadArg->fArgIGSlowRecursiveFibonacci (aThreadArg->fArg));
        
    free (theThreadArg);
        return 
    NULL;
    }

    static 
    void MyThreadWorkerWithDangerousCastToNatural (void theThreadArg){
        const 
    MyNatural aNumber = (MyNaturaltheThreadArg;
        
    printf ("%s: IGRecursiveFibonacci (%ld) = %ld;\n"__func__aNumberIGSlowRecursiveFibonacci (aNumber));
        return 
    NULL;
    }

    #define MY_NUM_THREADS 40

    int main (void){
        
    pthread_t aContainerOfThreadId [MY_NUM_THREADS];

        
    unsigned long i;
        
        
    assert (== IGSlowRecursiveFibonacci (1));
        
    assert (== IGSlowRecursiveFibonacci (2));
        
    assert (== IGSlowRecursiveFibonacci (3));
        
    assert (== IGSlowRecursiveFibonacci (4));
        
    assert (102334155 == IGSlowRecursiveFibonacci (40));

        for (
    0MY_NUM_THREADS; ++i){
            
    int aErr;
            
    SMyThreadArg aMyThreadArg malloc (sizeof (SMyThreadArg));
            
    assert (NULL != aMyThreadArg);
            
    aMyThreadArg->fArg 1;
            
    aErr pthread_create (&aContainerOfThreadId [i], NULLMyThreadWorkerWithStructaMyThreadArg);
            
    assert (== aErr);
        }

        for (
    0MY_NUM_THREADS; ++i){
            const 
    int aErr pthread_create (&aContainerOfThreadId [MY_NUM_THREADS], NULLMyThreadWorkerWithDangerousCastToNatural, (void *) (1));
            
    assert (== aErr);
        }

        
        
    printf ("waiting for threads;\n");

        for (
    0sizeof (aContainerOfThreadId) / sizeof (aContainerOfThreadId [0]); ++i){
            const 
    int aErr pthread_join (aContainerOfThreadId [i], NULL);
            
    assert (== aErr);
        }

        
    printf ("bye bye...\n");
        return 
    0;

    ;-)

  7. #7
    puoi mettere i valori che devi passare in un array per ciascun thread che crei cosi non devi gestire i semafori

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.