auf select basierender webserver



  • hi,

    bastele momentan an einem kleinen webserver, jetzt hätt ich mal ein paar fragen:

    • kann ein browser in der zeit wo ich eine anfrage beantworte schon eine weitere schicken, wenn keep-alive gesetzt ist? oder hab ich da was falsch verstanden?
    • im moment basiert das teil auf select ohne pthreads. damit komm ich bei einfachen anfragen auf +10k anfragen/s. wenn die anfrage lange dauert, weil z.b. viele zeilen aus der db kommen, geht aber nur eine anfrage gleichzeitig.(denke das hat jetzt nichts mit der verbindung zu tun, sondern mit der reinen arbeitszeit auf dem server.). alternativ hab ich einen thread pool, anfragen werden in eine queue geschrieben, und dann von den worker threads abgearbeitet. dann geht allerdings die performance total in die knie 😞
      gibts da eine andere/bessere lösung?
    • evtl. ist auch meine thread pool implementation kacke, hab das mit den pthread_cond_signal noch nicht gecheckt. könnt ihr da bitte mal über die zwei entscheidenden funktionen drüber schaun?

    besonders die auskommentierten zeilen check ich nicht. kann mir das evtl. mal einer richtig hinbiegen - bitte bitte 😋

    //worker funktion
    void *thread_pool_cb(void *args){
    	thread_pool_t *ARGS = args;
    	void *task = alloca(ARGS->tasks.size);
    
    	if(task){
    		//pthread_mutex_lock(&ARGS->tasks.mutex0);
    		while(1){
    			//pthread_cond_wait(&ARGS->tasks.cond,&ARGS->tasks.mutex0);
    			//puts("work --");
    			if(/*thread_pool_get_next_task()*/){
    				//do job
    			}else{
    				//no job
    			}
    		}
    		//pthread_mutex_unlock(&ARGS->tasks.mutex0);
    	}else{
    		//@todo: check error
    		puts("thread_pool_cb->alloca->error");
    	}
    
    	return 0;
    }
    
    //boss funktion
    int thread_pool_schedule(thread_pool_t *t,void *task){
    	int ret = 0;
    
    	//pthread_mutex_lock(&t->tasks.mutex0);
    	pthread_mutex_lock(&t->tasks.mutex1);
    
    	if(/*thread_pool_append_task()*/){
    		//pthread_cond_signal(&t->tasks.cond);
    		//pthread_cond_broadcast(&t->tasks.cond);
    		ret = 1;
    	}else{
    		//error
    	}
    	pthread_mutex_unlock(&t->tasks.mutex1);
    	//pthread_mutex_unlock(&t->tasks.mutex0);
    
    	return 0;
    }
    

    vielen dank schon mal :xmas1:



  • axo, die gibts auch noch

    int thread_pool_get_next_task(thread_pool_t *t,void *out){
    	size_t ret = 0;
    
    	pthread_mutex_lock(&t->tasks.mutex1);
    
    	if(/*thread_pool_has_next_task()*/){
    		//in *out geht normal noch der nächste task
    		ret = 1;
    	}else{
    		ret = 0;
    	}
    
    	pthread_mutex_unlock(&t->tasks.mutex1);
    
    	return ret;
    }
    


  • Und 10k Anfragen/s reichen dir nicht? :xmas1:



  • bemerker schrieb:

    Und 10k Anfragen/s reichen dir nicht? :xmas1:

    doch, das wär schon toll! aber ich hätt auch gern die pthreads - sonst blockiert einer mit einen exotischen anfrage alle anderen und die finden diese ungerechtigkeit dann sicher nicht lustig 😉



  • Nimm lieber epoll (Linux) oder kqueue (BSD) anstelle select. Bei select ist die Anzahl der Verbindungen stark begrenzt. Alternativ kannst du natürlich auch einen Wrapper wie libevent oder Boost.Asio verwenden. Threads solltest du nur benutzen, wenn du eine Anfrage hast, die wirklich länger braucht. Da das anlegen/verwalten von Threads einen entsprechenden Overhead mitbringt.

    Siehe auch http://www.kegel.com/c10k.html http://bulk.fefe.de/scalable-networking.pdf


Anmelden zum Antworten