[Resolvido] Problema de performance C++

21 respostas
Sad7

Bom dia pessoal, veja se alguem tem ideia do que esta acontecendo comigo:
No meu software trabalho com sockets e threas, pra cada conexao socket eu tenho 2 threads, minhas threads eu uso locks e sleeps de 10 millis para nao sobrecarregar.
Minhas threads sao as da biblioteca boost e meu socket eh uma classe que eu encontrei na internet, o sistema só processa algo quando chega requisição do socket, em outro caso fica parado esperando requisição, porem mesmo quando esta parado, ele esta ocupando 99% de processamento da minha maquina, eu nao sei onde eu posso mexer para corrigir este problema, eu pensei na classe socket, mais nao sei c poderia resolver, alguem ja teve algum problema assim ou tem ideia do que pode estar acontecendo?!

Grato.

21 Respostas

vhmolinar

Quando você diz minhas threads, ao que você está se referindo?
Porque vamos pela lógica, você teria uma thread apenas para leitura e cacheamento de mensagens certo?

Então supondo que ninguém está escrevendo no socket assim como você disse

você só teria 2 threads rodando de fato no seu sistema, a principal e a sub responsável pela leitura no socket.

E em cada disparo de nova conexão você criaria 2 outras threads (custoso demais isso já te digo), então me diga em qual estado estaria sua thread consumer neste ponto.
Sua api de socket segura a thread de leitura até receber uma nova mensagem? Como que você faz ela esperar novas mensagens?

*** Sobre as 2 threads, isso é ruim, pense em um pool para respostas soa melhor como solução.

J

Você precisa setar a prioridade da thread como normal ou baixa. Dessa maneira o so não vai pedir tanto processamento para elas.

Porque você não usa um framework que já tem esse tipo de solução implementada?

Existem vários como o gtk, wxWidgets e qt;

http://qt.nokia.com/
http://www.wxwidgets.org

Sad7


minhas threads eu uso locks e sleeps de 10 millis para nao sobrecarregar.

Quando você diz minhas threads, ao que você está se referindo?
Porque vamos pela lógica, você teria uma thread apenas para leitura e cacheamento de mensagens certo?

A primeira thread é a de leitura que le a mensagem vinda do cliente, monta um objeto com os parametros lidos na mensagem e coloca numa fila de processamento.
A segunda thread fica verificando essa fila de processamento e processa meu objeto, logo depois envia uma string para o client.

exatamente, minha thread principal esta parada ate que receba uma nova mensagem,
enquanto a segunda thread(processamento e envio) fica verificando a fila de processamento.

Sad7

juliocbq:
Você precisa setar a prioridade da thread como normal ou baixa. Dessa maneira o so não vai pedir tanto processamento para elas.

Porque você não usa um framework que já tem esse tipo de solução implementada?

Existem vários como o gtk, wxWidgets e qt;

http://qt.nokia.com/
http://www.wxwidgets.org

desculpa a ignorancia mais veja se eu entendi, estou usando as threads da biblioteca boost, eu teria que troca-las por essas que vc me passou?!

E

Sad7:
Bom dia pessoal, veja se alguem tem ideia do que esta acontecendo comigo:
No meu software trabalho com sockets e threas, pra cada conexao socket eu tenho 2 threads, minhas threads eu uso locks e sleeps de 10 millis para nao sobrecarregar.
Minhas threads sao as da biblioteca boost e meu socket eh uma classe que eu encontrei na internet, o sistema só processa algo quando chega requisição do socket, em outro caso fica parado esperando requisição, porem mesmo quando esta parado, ele esta ocupando 99% de processamento da minha maquina, eu nao sei onde eu posso mexer para corrigir este problema, eu pensei na classe socket, mais nao sei c poderia resolver, alguem ja teve algum problema assim ou tem ideia do que pode estar acontecendo?!

Grato.

Hum… você precisa estabelecer 2 threads para cada socket? Quando se usa boost::asio, é aconselhável usar menos sockets que threads, e usar processamento assíncrono. Concordo que isso é bem mais complicado para trabalhar, mas você pode ter desempenho melhor.

vhmolinar

Sad7:

minhas threads eu uso locks e sleeps de 10 millis para nao sobrecarregar.

Quando você diz minhas threads, ao que você está se referindo?
Porque vamos pela lógica, você teria uma thread apenas para leitura e cacheamento de mensagens certo?

A primeira thread é a de leitura que le a mensagem vinda do cliente, monta um objeto com os parametros lidos na mensagem e coloca numa fila de processamento.
A segunda thread fica verificando essa fila de processamento e processa meu objeto, logo depois envia uma string para o client.

exatamente, minha thread principal esta parada ate que receba uma nova mensagem,
enquanto a segunda thread(processamento e envio) fica verificando a fila de processamento.

Ta se você tem uma thread para resposta, porque é que você starta 2 outras a cada nova conexão?
Para ser mais exato, ao startar o sistema, sem que nenhuma conexão seja feita, quantas threads passam a existir?

E outra não acredito que isso seja problema de escalonamento uma vez que vocês estão quereno setar prioridades. Mas se de tudo for de extrema necessidade setar prioridades você pode muito bem fazer sem sair do boost. O boost é a MELHOR e mais COMPLETA biblioteca existente para desenvolvimento c++.

E

Normalmente você não precisa mexer em prioridades de threads quando se usa threads. Se você acha que precisa fazer isso, você está fazendo alguma coisa errada.

vhmolinar

Agreed :!:

Sad7

Veja se da pra entender melhor assim, eu tenho uma thread de envio e uma de resposta para cada cliente conectado e apenas uma fila para processamento, ou seja, todos os clientes postam numa unica fila que eh verificada pelas threads de envio, entao vc me pergunta, pra q fazer duas threads de envio?! pq no meu processamento eu uso uma api particular que precisa de um objeto dela por cliente.

E enquanto eu nao tenho cliente conectado nao esta rodando nehuma thread( e ai o processamento da maquina esta zerado, quando um cliente conecta, o processamento vai para 99% mesmo sem ter requisição).

entao, estou usando a thread do boost, porem o socket nao eh, poderia ser o socket o problema?!

vhmolinar

Sad7:

Ta se você tem uma thread para resposta, porque é que você starta 2 outras a cada nova conexão?
Para ser mais exato, ao startar o sistema, sem que nenhuma conexão seja feita, quantas threads passam a existir?

Veja se da pra entender melhor assim, eu tenho uma thread de envio e uma de resposta para cada cliente conectado e apenas uma fila para processamento, ou seja, todos os clientes postam numa unica fila que eh verificada pelas threads de envio, entao vc me pergunta, pra q fazer duas threads de envio?! pq no meu processamento eu uso uma api particular que precisa de um objeto dela por cliente.

E enquanto eu nao tenho cliente conectado nao esta rodando nehuma thread( e ai o processamento da maquina esta zerado, quando um cliente conecta, o processamento vai para 99% mesmo sem ter requisição).

entao, estou usando a thread do boost, porem o socket nao eh, poderia ser o socket o problema?!

Não sei qual socket está usando, então não da pra saber. Tenta usar o boost::asio, funciona!

E sobre seu modelo de arquitetura, tenta utilizar uma trhead para o socket, eu digo, para leitura do mesmo, independente de quantas conexões. Onde a cada leitura ela cachea o que leu em uma fila, para que assime então uma outra ou outras threads leiam essa fila(sincronizadamente), processem e respondam a mensagem para o cliente.

Assim teoricamente você manteria no mínimo 2 threads rodando e no máximo quantas conexões existirem.

E outra você já debugou sua aplicação para saber quantas vezes o socket está notificando novas conexões a cada nova conexão?
Pense que se você abre thread a cada conexão e que se seu socket notifica erroneamente então você vai abrir mais de uma thread sem necessidade. Pode ser esse o problema. Então por segurança utilize os sockets do boost::asio.

Sad7

eu acho que nao estou conseguindo ser muito claro =/
vou tentar passar meu problema completo entao:

o Server serve somente para processamento
1 Server para 1Cliente (sera sempre este cenário)
porem o cliente pode abrir varias conexoes com o server (para aumentar o numero de processamento)
cada conexao eu preciso instanciar um novo objeto que contem os metodos de processamento.

ql seria a ideia para o caso?!

Sad7

estou procurando algum exemplo de multithread do asio, mais nao ta meio complicado, se tiver algum exemplo meio simples de entender que puder me passar eu ficaria grato.

mais se eu trabalhar com apenas uma thread q recebe, eu terei uma lentidao de processamento, onde a ideia de abrir duas threds para receber eh aumentar o numero de processamento. (recebo duas mensagens de uma vez, processo duas mensagens de uma vez e assim sucessivamente).

sim, jah foi debugado e esta abrindo as conexoes e threads corretamente.

sinceramente eu nao vejo problema nessa arquitetura pois a maquina esta batendo 99% com apenas 1 conexao, ou seja, com apenas uma thread de recebimento e outra de envio, por isso creio que nao seja as threads o problema e sim o socket.

Sad7

entao creio que no meu caso isso daria certo neh?! pois eu preciso de 1 socket pra cada 2 threads.

Sad7

Pronto, o problema nao eh o socket,
eu aumentei o sleep da thread de envio (que fica verificando a fila) para 2 segundos, e o processamento nao chega nem a 5%

a minha thread esta assim:

while (sock->getStatus()) {
		try {
			sem_wait(&lock_proc);
			if (!queueProcessing.empty()){
				pessoaRecebida = queueProcessing.front();
				queueProcessing.pop();
				hasPessoa = true;
			}
			sem_post(&lock_proc);

			if(hasPessoa) {
				//processamento...
			}
		} catch (SocketException &ex) {
			if (hasPessoa) {
				sem_wait(&lock_proc);
				queueProcessing.push(pessoaRecebida);
				sem_post(&lock_proc);
			}
		}

		hasPessoa = false;
		sleep(2); // aqui que estava 0.01 e batendo 99%
	}

no java eu resolvo isso colocando um filaProcessing.wait dai quando eu adiciono na fila eu sou um notifyAll alguem sabe como eu posso fazer isso no C++?

E

http://www.boost.org/doc/libs/1_43_0/doc/html/thread/synchronization.html#thread.synchronization.condvar_ref

ViniGodoy

Por que você não usa a boost::asio para os sockets?

Sad7

pq eu nao consegui entender os exemplos q eu encontrei de asio multithread
=/

Sad7

irei testar esse, acho q vai dar certo =D

vhmolinar

Exemplos:

http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/examples.html

Tutoriais:

http://www.boost.org/doc/libs/1_43_0/doc/html/boost_asio/tutorial.html

:slight_smile:

Sad7

Aee…
o esquema de notify e wait funcionou perfeitamente,
agora ta batendo 25% soh quando tem objeto pra processar, senao nao bate nem 1%…
agora vou tentar implementar o socket boost, jah q vcs disseram q eh melhor.

Brigadao ae tdo mundo…
:smiley:

J

Sad7:
juliocbq:
Você precisa setar a prioridade da thread como normal ou baixa. Dessa maneira o so não vai pedir tanto processamento para elas.

Porque você não usa um framework que já tem esse tipo de solução implementada?

Existem vários como o gtk, wxWidgets e qt;

http://qt.nokia.com/
http://www.wxwidgets.org

desculpa a ignorancia mais veja se eu entendi, estou usando as threads da biblioteca boost, eu teria que troca-las por essas que vc me passou?!

O que eu quis dizer é que você está usando as threads da boost que são ótimas, e você está criando a solução na mão. Esses frameworks que citei já possuem essas soluções implementadas e são muito boas. Mas se o problema já foi resolvido blz.

Criado 4 de junho de 2010
Ultima resposta 4 de jun. de 2010
Respostas 21
Participantes 5