<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>Caloni.com.br</title>
	<link>http://www.caloni.com.br/blog</link>
	<description>C++, Windows, Programação, Depuração e Transpiração</description>
	<pubDate>Thu, 18 Jun 2009 11:35:09 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>Programadores de verdade não usam Java</title>
		<link>http://www.caloni.com.br/blog/archives/programadores-de-verdade-nao-usam-java</link>
		<comments>http://www.caloni.com.br/blog/archives/programadores-de-verdade-nao-usam-java#comments</comments>
		<pubDate>Thu, 18 Jun 2009 11:21:15 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/programadores-de-verdade-nao-usam-java</guid>
		<description><![CDATA[Quando era um newbie (e um wanna-be) gostava de ler o "Real Programmers Don't Use Pascal", um texto humorístico que mais me influenciou e encorajou a caminho da iluminação C/C++ do que o livro de K&#38;R. A partir dele, supunha eu, ser um "programador de verdade" era ser tudo. Ser um Quiche Eater (Comedor de [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/real-programmer.png" title="Real Programmer" alt="Real Programmer" width="204" align="left" height="174" />Quando era um <a href="http://www.caloni.com.br/blog/archives/o-passado-torto-de-um-programador-por-acaso" title="Passado torto de um programador por acaso"><em>newbie</em></a> (e um <a href="http://www.caloni.com.br/blog/archives/barata-eletrica-e-o-hacker-de-antigamente" title="Barata elétrica e o hacker de antigamente"><em>wanna-be</em></a>) gostava de ler o "<a href="http://rixstep.com/2/2/20071015,00.shtml" title="Real Programmers Don't Use Pascal">Real Programmers Don't Use Pascal</a>", um texto humorístico que mais me influenciou e encorajou a caminho da iluminação C/C++ do que o <a href="http://www.caloni.com.br/blog/archives/the-c-programming-language" title="The C Programming Language">livro de K&amp;R</a>. A partir dele, supunha eu, ser um "programador de verdade" era ser tudo. Ser um Quiche Eater (Comedor de Torta) não era nada. Programadores de verdade é que resolvem os problemas de verdade! Quiche Eaters são os losers que estudam os conceitos acadêmicos da ciência da computação e nunca fazem um maldito programa que preste (conhece alguém assim?).</p>
<p>Piadas à parte, para mim o humor do texto ainda pode ser aproveitado por aqueles que já se acham muito bons e acreditam não terem mais como crescer profissionalmente. Quando <a href="http://www.caloni.com.br/blog/archives/entrevista-com-o-caloni-no-do-zero-ao-mestre" title="Entrevista">meu ego infla demais</a>, ainda me lembro que enquanto programo com <a href="http://www.caloni.com.br/blog/archives/retorno-do-pathisdirectory" title="PathIsDirectory">APIs de brincadeirinha</a> e um <a href="http://www.caloni.com.br/blog/archives/por-que-minha-dll-travou" title="Por que minha DLL travou?">sistema operacional</a> que é uma piada tem gente <a href="http://www.ccppbrasil.org/wiki/Bugs_dif%C3%ADceis_de_achar" title="Bugs difíceis de achar">projetando uma nave</a> que vai sair da órbita do Sistema Solar!</p>
<p>Por outro lado, muitas pessoas recém-saídas da faculdade de computação ainda acham programação uma matéria difícil. Esse texto nos lembra que difícil era a vida 20, 40, 70 anos atrás, quando engenheiros e programadores eram a mesma pessoa, e quando se você não soubesse o que estava fazendo colocaria projetos de milhões em risco.</p>
<p>Por consequência, o programador de verdade vive no passado. E ele sempre se valoriza frente ao povão jovem, porque ele sabe resolver aquele problema de tela azul que mais ninguém sabe. E como eu costumo dizer, parafraseando uma <a href="http://pt.wikipedia.org/wiki/Fausto_Silva" title="Fausto Silva">figura ilustre</a> da televisão brasileira, quem tem medo de abrir o Visual Studio e em vez disso fica projetando eternamente o software não vai muito longe: "quem sabe faz na hora!".</p>
<p>Aqui segue um breve resumo do texto original adaptado para os tempos atuais e com a minha visão preconceituosa de pensar sobre o assunto. Se quiser, use sua parte politicamente correta da mente e critique à vontade!</p>
<p><strong>Linguagens</strong>. Lembre-se: inventar que você precisa de mais linguagens/recursos para fazer seu trabalho é lembrar que você é incompetente o suficiente para inventar esse tipo de desculpinha. Você é daqueles que diz "cada problema tem sua ferramenta específica" ou algo do tipo. Ou seja, um programador politicamente correto e ineficiente. Não vê que tudo o que você precisa está na linguagem C. Se não estiver, então está no assembly. Se não estiver nem no C nem no assembly não vale a pena ser pensado a respeito.</p>
<p><strong>Programação Estruturada</strong>. É o primeiro e último paradigma a ser aplicado. Afinal de contas, Orientação a Objetos é mais uma desculpinha para não programar. São abstrações e mais abstrações para inventar que, uma vez que você é um peso morto que não consegue resolver um problema com funções e variáveis, precisa de classes, herança, templates e outras tranqueiras que vão transformar seu código simples e reto em uma cornucópia mágica que só vai impressionar os outros pela inutilidade e complexidade da solução!</p>
<p><strong>Estrutura de dados</strong>. Outro ótimo conceito para enganar a si mesmo. Hoje são muitos os que se escravizam nos leiautes SQL e classes estranhas de <em>frameworks</em> estranhos que fazem todo o trabalho. Todos sabemos que a única estrutura realmente útil de saber é o array. O resto são variantes do mesmo tema: filas e pilhas.</p>
<p><strong>Sistema operacional</strong>. Mac e Windows são brinquedinhos e Linux é um vídeo-game que dá mais trabalho de configurar do que de jogar. O programador de verdade usa algo como mainframes ou qualquer outro sistema operacional beta, que são bem esquisitos de mexer e que podem fazer um verdadeiro estrago nas mãos de quem não tiver lido TODO o manual. E saber todos os bugs conhecidos e importantes do <em>kernel</em> e sua localização de cor na hora de bootar é vital.</p>
<p><strong>Ferramentas</strong>. Se você depende de uma IDE que tem Code Completion e outros penduricalhos do tipo, ou depende de algum outro editor seu favorito com seus 17459 plugins instalados, então você não é um programador de verdade. um programador de verdade usa o que tiver à mão na hora que precisar, seja um notepad, um hexdump ou até mesmo alguns beeps. A ferramenta não é limite para quem sabe programar de verdade.</p>
<p><strong>Depuração</strong>. Vai dizer que precisa do código-fonte para depurar? Então você não faz a mínima ideia do que o programa faz. Apenas algumas olhadas na <a href="http://www.caloni.com.br/blog/archives/aprendendo-assembly-com-o-depurador" title="Pilha"><em>call stack</em></a> e nos <a href="http://www.caloni.com.br/blog/archives/basico-do-basico-assembly" title="Assembly">registradores</a> podem fazer um programador de verdade solucionar um bug que os comedores de torta não conseguiriam depois de analisar aqueles gráficos UML com caixinhas dentro e casos de uso por meses a fio.</p>
<p>O <strong>Trabalho</strong> de programadores de verdade com certeza não é fazer programinhas que acessam basezinhas de SQL com opção de consulta e cadastro. Nem são aqueles saitezinhos com PHP/Apache, scripts e mais scripts. Não, senhor. São programas que lidam com o Sistema Operacional de uma forma mais íntima (criptografia de HD, drivers de File System, serviços de comunicação crítica, etc), ou são programas que fazem algo de verdadeiramente útil (compiladores, o próprio sistema operacional). Ou tavez que mexam diretamente com hardware (microcontroladores complexos, robôs, naves, aparelhagem médica, etc).</p>
<p>A <strong>Diversão</strong> de todo programador de verdade é conversar com os amigos (sobre programação), ler alguma coisa (sobre programação) e assistir filmes inteligentes (sobre programação ou pessoas que fizeram algum tipo de desafio intelectual "na marra"). Existe algo mais divertido que isso?</p>
<p>E, por fim, em seu <strong>Habitat Natural</strong>, poderemos encontrar páginas de código assembly espalhadas em volta da mesa, um computador travado por uma depuração remota de kernel por cabo serial, algumas anotações em hexa em um pedaço de papel, algumas dezenas de páginas abertas no navegador sobre comportamento das funções BIOS em HDs SATA com mais de 500 GB trabalhando em RAID4, café, salgadinhos, manchas no carpete. Quando não há nada para fazer, o ambiente está arrumadíssimo e não se nota a presença de programadores de verdade à vista.</p>
<p>E o <strong>Futuro</strong> do programador de verdade? Bom, a linguagem C pode até estar morrendo. Mas, e daí? Essa tal de C++ ainda suporta ponteiros. O resto das abstrações afeminadas como classes e herança podem ser totalmente ignoradas. O <a href="http://brazil.joelonsoftware.com/Articles/BacktoBasics.html" title="De volta às raízes">básico</a> sempre existirá. Esqueça as versões com herança múltipla e o enigmático <em>concepts</em>. Seja homem!</p>
<p>O fato é que, independente de quanto mais o mundo se tornar "gerenciado" por trás de frameworks e programadores que preferem "fazer projetos" atrás de seus pacotes de escritório e casos de uso, quando algum problema pipocar, algum bug tenebroso ameaçar a vida útil de um projeto, um programador de verdade estará lá para salvar o dia, pois só um programador de verdade sabe fazer o seu trabalho. E bem feito.</p>
<p>PS: Na verdade, me lembrei. Eu peguei esse cacoete de falar "quem sabe faz na hora" do meu amigo <a href="http://codebehind.wordpress.com/" title="Code Behind">Thiago</a>. Ele também dizia "se vira nos 30!". Bom, se eu citar todas as frases brilhantes que ele usava quando trabalhávamos juntos o texto vai ficar bem longo =)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/programadores-de-verdade-nao-usam-java/feed</wfw:commentRss>
		</item>
		<item>
		<title>Como compilar em somente um passo</title>
		<link>http://www.caloni.com.br/blog/archives/como-compilar-em-somente-um-passo</link>
		<comments>http://www.caloni.com.br/blog/archives/como-compilar-em-somente-um-passo#comments</comments>
		<pubDate>Mon, 25 May 2009 09:00:04 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Controle de Fonte]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/como-compilar-em-somente-um-passo</guid>
		<description><![CDATA[Uma das primeiras perguntas do teste do Joel é saber se você pode compilar todo o projeto em apenas um passo. Essa é uma questão essencial e um desafio para muitas equipes. Perdem-se horas sagradas para gerar um novo Release.
Compilação automática geralmente está disponível nas ferramentas de desenvolvimento. Se você estiver usando o Visual Studio, [...]]]></description>
			<content:encoded><![CDATA[<p>Uma das primeiras perguntas do <a href="http://brazil.joelonsoftware.com/Articles/TheJoelTest.html" title="Teste de qualidade do Joel">teste do Joel</a> é saber se você pode compilar todo o projeto em apenas um passo. Essa é uma <strong>questão essencial</strong> e um desafio para muitas equipes. Perdem-se horas sagradas para gerar um novo Release.</p>
<p>Compilação automática geralmente está disponível nas ferramentas de desenvolvimento. Se você estiver usando o Visual Studio, por exemplo, é possível fazer isso com uma linha:</p>
<pre>devenv minha-solução.sln /Rebuild Release</pre>
<p>Se não for exatamente o que você precisa, basta fazer uma <a href="http://www.google.com/search?q=visual%20studio%20automatic%20build">pesquisa de quinze minutos</a> e encontrar os parâmetros corretos. O objetivo é: <strong>eu rodo esse comando em cima do projeto inteiro em uma máquina zerada e ele simplesmente compila</strong>.</p>
<h4>Múltiplas soluções</h4>
<p>É lógico que ter apenas um <em>solution/workspace</em> para guardar projetos médios e grandes é inviável. Demora para carregar no ambiente e possuem dezenas de dependências. Isso já foi tentado duas vezes nas duas empresas em que trabalhei e não funcionou. Talvez por isso seja necessário criar um <em>script</em> que rode o comando acima para todas as soluções do projeto, o que não muda muito o <em>modus operandi</em> da coisa:</p>
<pre>call :Build ..\Libraries\Libraries.sln
call :Build ..\Services\Services.sln
call :Build ..\Drivers\Drivers.sln
call :Build ..\Tools\Tools.sln
goto :eof</pre>
<pre>:Build
echo %1...
devenv "%1" /Rebuild Release
exit /b %errorlevel%</pre>
<p>Note que meu script usa a <a href="http://www.caloni.com.br/blog/archives/projeto-modelo" title="Projeto-modelo">estrutura padronizada dos diretórios de um projeto</a>, onde cada tipo de componente tem sua pasta e solução.</p>
<p>Aos poucos você pode ir colocando "frescurinhas" em seu build (executa Debug e Release, roda automatizado no servidor, faz testes unitários, incrementa o número da versão, ...), mas algumas premissas sempre se mantêm:</p>
<ul>
<li>Deve ser possível compilar o projeto inteiro em um passo</li>
<li>Deve ser possível usar qualquer máquina de desenvolvimento para isso</li>
</ul>
<p>Regras simples de ser seguidas se você usar sempre a máxima do <a href="http://en.wikipedia.org/wiki/KISS_principle" title="Keep it Simple, Stupid!">KISS</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/como-compilar-em-somente-um-passo/feed</wfw:commentRss>
		</item>
		<item>
		<title>Meu roteiro C++</title>
		<link>http://www.caloni.com.br/blog/archives/meu-roteiro-c</link>
		<comments>http://www.caloni.com.br/blog/archives/meu-roteiro-c#comments</comments>
		<pubDate>Wed, 20 May 2009 11:13:27 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/meu-roteiro-c</guid>
		<description><![CDATA[Como não consigo mais ter ideias para artigos, resolvi catalogar todas as coisas que já falei nesse blogue e, o mais importante, todas as coisas que ainda não falei nesse blogue (e espero um dia falar ou talvez nunca fale), começando por C++, que era o intuito original (só que não é mais, porque eu [...]]]></description>
			<content:encoded><![CDATA[<p>Como não consigo mais ter ideias para artigos, resolvi catalogar todas as coisas que já falei nesse blogue e, o mais importante, todas as coisas que ainda não falei nesse blogue (e espero um dia falar ou talvez nunca fale), começando por C++, que era o intuito original (só que não é mais, porque eu uso mais a Win32 API que a STL):</p>
<h4>C++</h4>
<ul>
<li>História
<ul>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-1" title="História da Linguagem C - Parte 1">A linguagem BCPL</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-1" title="História da Linguagem C - Parte 1">O código-objeto</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-2">A linguagem B</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-2">A "função" char</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-2">O primeiro printf da história</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/the-c-programming-language">A linguagem C</a></li>
<li>A linguagem C++</li>
<li>As influências</li>
</ul>
</li>
<li>Conceitos
<ul>
<li><a href="http://www.caloni.com.br/blog/archives/guia-basico-para-programadores-de-primeiro-int-main">O conceito programa</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/historia-da-linguagem-c-parte-1" title="História da Linguagem C - Parte 1">O código-objeto</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/os-diferentes-erros-na-linguagem-c">Processo de compilação</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/declaracao-x-definicao">Declaração x definição</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/basico-do-basico-tipos">Tipos</a></li>
<li>Lvalue x Rvalue</li>
<li>A passagem por valor</li>
<li><a href="http://www.caloni.com.br/blog/archives/basico-do-basico-ponteiros">Ponteiros</a></li>
<li>Estruturas e classes</li>
<li>Espaços de nomes</li>
<li>Polimorfismo estático</li>
<li>Herança</li>
<li>Polimorfismo dinâmico</li>
<li>Iteradores</li>
<li>Função-objeto</li>
<li>Templates</li>
<li>Algoritmos genéricos</li>
<li>Qualificadores (traits)</li>
<li><a href="http://www.caloni.com.br/blog/archives/aquisicao-de-recurso-e-inicializacao">O conceito RAII</a></li>
</ul>
</li>
<li>Linguagem
<ul>
<li><a href="http://www.caloni.com.br/blog/archives/curiosidades-inuteis-o-operador-de-subscrito-em-c">O operador de subscrito</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/protecao-dos-membros-protected">A proteção protected</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/sizeof-de-novo">Sizeof e strings literais</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/reflexao-em-c">Uso de reflexão com typeid</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/typeid-e-os-perigos-do-nao-polimorfismo">Typeid e o polimorfismo</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/ponteiros-de-metodo-conceito-fundamental">Ponteiros de método</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/ponteiro-de-metodo-qual-this-e-usado">Ponteiros de método e o this</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/try-catch-flutuante">Try-catch fora do corpo da função</a></li>
<li>Sobrecarga de operadores</li>
</ul>
</li>
<li>Biblioteca
<ul>
<li><a href="http://www.caloni.com.br/blog/archives/usando-a-libc-nativa-do-windows">Biblioteca C no Windows</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/a-mobilidade-das-variaveis-no-printf">Mobilidade da pilha com prinff</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/iteradores-nao-sao-constantes">Erros comuns de iteradores</a></li>
<li>STL</li>
<li>Boost</li>
</ul>
</li>
<li>Dicas
<ul>
<li><a href="http://www.caloni.com.br/blog/archives/os-diferentes-erros-na-linguagem-c">Erros comuns de iniciantes</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/codigos-de-entrevista-o-ponteiro-nulo">Ponteiro nulo em entrevistas</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/quando-o-ponteiro-nulo-nao-e-invalido">Nem todo ponteiro nulo é inválido</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/desconstruindo-ioccc">Decifrando código obscuro</a></li>
<li><a href="http://www.caloni.com.br/blog/archives/aquele-do-while-engracado">Usando do-while para evitar erros de macro</a></li>
<li>Sobrecarga por tipo de retorno</li>
</ul>
</li>
</ul>
<p>Espero que isso me ajude a continuar completando as lacunas do saite. Se não der certo, pelo menos já sei o que fiz.</p>
<p>Sugestões?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/meu-roteiro-c/feed</wfw:commentRss>
		</item>
		<item>
		<title>English posts</title>
		<link>http://www.caloni.com.br/blog/archives/english-posts</link>
		<comments>http://www.caloni.com.br/blog/archives/english-posts#comments</comments>
		<pubDate>Sat, 09 May 2009 04:57:05 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[English]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/english-posts</guid>
		<description><![CDATA[Now the English subject on Caloni.com.br will be available on the  English blog. That means the feeds will be separated as well. Whoever wants to accomplish both blogs should to subscribe to both feeds, English and Portuguese ones.
]]></description>
			<content:encoded><![CDATA[<p>Now the English subject on Caloni.com.br will be available on the  <a href="http://caloni.com.br/blog/en" title="Caloni.com.br English blog">English blog</a>. That means the feeds will be separated as well. Whoever wants to accomplish both blogs should to subscribe to both feeds, <a href="http://www.caloni.com.br/blog/en/feed" title="English feed">English</a> and <a href="http://www.caloni.com.br/blog/feed" title="Portuguese feed">Portuguese</a> ones.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/english-posts/feed</wfw:commentRss>
		</item>
		<item>
		<title>Últimas pesquisas na blogosfera nacional</title>
		<link>http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional</link>
		<comments>http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional#comments</comments>
		<pubDate>Fri, 08 May 2009 10:50:40 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional</guid>
		<description><![CDATA[ É um imenso prazer constatar que hoje, mais de dez anos depois de eu ter iniciado minha caminhada pelo mundo da programação C/C++, temos uma reação de blogues e saites prontos para elucidar questões simples e avançadas dessas duas linguagens que ainda não morreram e, se depender de como as coisas andam, ainda vão [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/brasil-matrix.png" title="Mapa do Brasil com o código do filme Matrix" alt="Mapa do Brasil com o código do filme Matrix" align="left" /> É um imenso prazer constatar que hoje, mais de dez anos depois de eu ter iniciado minha caminhada pelo mundo da programação C/C++, temos uma reação de blogues e saites prontos para elucidar questões simples e avançadas dessas duas linguagens que ainda não morreram e, se depender de como as coisas andam, ainda vão durar pelo menos mais uns dez anos (sim, não sou tão otimista assim).</p>
<p>Esse artigo é só para constar em minha lista de referência para o aprendizado de C, C++ e todas as outras coisas que vem depois. Se eu tivesse que escrever isso lá no início, provavelmente recomendaria mais linques de livros e saites em inglês. Hoje, felizmente, temos um conteúdo em pleno desenvolvimento em nossa blogosfera tupiniquim. E espero que continue assim!</p>
<h4>C/C++</h4>
<ul>
<li><a href="http://bcsanches.wordpress.com/2008/12/11/strings-em-c/">Strings</a></li>
<li><a href="http://bcsanches.wordpress.com/2009/01/23/strings-e-numeros/">Strings e Números</a></li>
<li>Os <a href="http://bcsanches.wordpress.com/2008/08/27/c-type-casting-1%c2%aa-parte/">diversos</a> <a href="http://bcsanches.wordpress.com/2008/09/18/c-type-casting-2%c2%aa-parte/">tipos</a> de <a href="http://bcsanches.wordpress.com/2008/11/05/c-type-casting-3%c2%aa-e-ultima-parte/">casting</a></li>
<li><a href="http://blog.blabos.org/2009/04/ponteiros-e-referencias-em-c-parte-1/">Pointeiros</a> e <a href="http://blog.blabos.org/2009/05/ponteiros-e-referencias-em-c-parte-2/">Referências</a></li>
<li><a href="http://www.thradams.com/codeblog/templates.pdf">Templates</a></li>
<li><a href="http://bcsanches.wordpress.com/2008/05/29/smart-pointers-introducao/">Smart Pointer - Introdução</a></li>
<li><a href="http://bcsanches.wordpress.com/2008/06/10/auto-pointers/">Auto Pointer (auto_ptr)</a></li>
<li>Boost <a href="http://bcsanches.wordpress.com/2008/07/09/boost-shared-pointers/">Shared Pointer</a>, <a href="http://bcsanches.wordpress.com/2008/07/17/boost-weak-pointer-weak_ptr/">Weak Pointer</a> e <a href="http://bcsanches.wordpress.com/2008/07/09/boost-shared-pointers/">Scoped Pointer</a></li>
<li>Boost <a href="http://bcsanches.wordpress.com/2008/07/30/boost-shared-array-e-scoped-array-shared_array-e-scoped_array/">Shared Array e Scoped Array </a></li>
<li><a href="http://devhints.blogspot.com/2008/12/c-quando-usar-cada-smart-pointer.html">Quando usar cada um dos smart pointers</a></li>
<li><a href="http://groups.google.com/group/ccppbrasil/topics">As infinitas e riquíssimas discussões na lista C/C++</a></li>
</ul>
<h4>Visual Studio</h4>
<ul>
<li><a href="http://bcsanches.wordpress.com/2009/03/06/como-utilizar-o-visual-studio-c-parte-1/">Como usar</a> o <a href="http://bcsanches.wordpress.com/2009/04/01/como-utilizar-o-visual-studio-c-parte-2/">Visual</a> <a href="http://bcsanches.wordpress.com/2009/04/22/como-utilizar-o-visual-studio-parte-3/">Studio</a></li>
<li><a href="http://bcsanches.wordpress.com/2008/05/14/compilando-a-boost-no-windows-usando-visual-studio/">Compilando o Boost no Windows (usando Visual Studio)</a></li>
</ul>
<h4>Mais assuntos?</h4>
<p>A internet brasileira cresceu como um todo. Mesmo que você deseje saber mais sobre <a href="http://dqsoft.blogspot.com/search/label/Processadores">microprocessadores</a> ou <a href="http://www.driverentry.com.br">drivers para Windows</a>, em português, hoje isso é possível. É claro que o que não é possível é você se dedicar profissionalmente a essas áreas <a href="http://www.caloni.com.br/blog/archives/developer-you-need-to-know-english" title="Developer you need to know English">sem saber inglês</a>. Mas é uma muito bem-vinda manifestação das pessoas que fazem acontecer todas essas coisas em nosso país.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/ultimas-pesquisas-na-blogosfera-nacional/feed</wfw:commentRss>
		</item>
		<item>
		<title>A sala da fila das threads</title>
		<link>http://www.caloni.com.br/blog/archives/a-sala-da-fila-das-threads</link>
		<comments>http://www.caloni.com.br/blog/archives/a-sala-da-fila-das-threads#comments</comments>
		<pubDate>Fri, 17 Apr 2009 01:37:49 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Código]]></category>

		<category><![CDATA[Sistema Operacional]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/a-sala-da-fila-das-threads</guid>
		<description><![CDATA[

Quando falei sobre a fila das threads, e como cada thread espera pacientemente em uma fila até chegar sua vez de ser atendida no guichê das CPUs, também vimos como é fácil fazer caquinhas em um programa que roda paralelamente duas threads ou mais.
Também falei que iríamos resolver esse problema, afinal de contas, temos que [...]]]></description>
			<content:encoded><![CDATA[

<p>Quando <a href="http://www.caloni.com.br/blog/archives/a-fila-das-threads" title="A fila das threads">falei sobre a fila das threads</a>, e como cada thread espera pacientemente em uma fila até chegar sua vez de ser atendida no guichê das CPUs, também vimos como é fácil fazer caquinhas em um programa que roda paralelamente duas threads ou mais.</p>
<p>Também falei que iríamos resolver esse problema, afinal de contas, temos que salvar todos aqueles programas que usam dezenas de threads trabalhando ao mesmo tempo para contar números de um até dez.</p>
<p>A boa notícia é que o salvamento é mais simples do que parece: coloque todas as suas threads em uma sala trancada e deixe apenas uma chave. As threads terão que brigar para sair da sala e, depois que a vencedora sair, as outras terão que ficar esperando ela voltar.</p>
<p>Confuso? Se estiver, ainda bem. Isso quer dizer que estamos novamente em um daqueles artigos com "pseudo-parábolas", a maneira mais ilustrada de explicar as coisas.</p>
<h4>A chave</h4>
<p>Os SOs modernos possuem inúmeras maneiras de controlar e monitorar o acesso a recursos do sistema. Neste breve artigo irei falar apenas de um: o <strong><em>critical section</em></strong>, ou, em tradução livre, "seção crítica". O "seção" desse nome diz respeito a uma seção do programa, ou seja, um pedaço de código mesmo. Um pedaço de código crítico.</p>
<p>Resumidamente, um critical section é um recurso que <strong>apenas uma thread por vez pode obter</strong>. Para que outra thread tenha acesso ao mesmo critical section, a primeira thread que o obteve deve soltá-lo. Enquanto ela não solta, as outras threads ficam paradas, esperando pela chave, na sala trancada.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/threads-room.png" title="Threads Room"></a></p>
<p style="text-align: center"><a href="http://www.caloni.com.br/blog/wp-content/uploads/threads-room.png" title="Threads Room"><img src="http://www.caloni.com.br/blog/wp-content/uploads/threads-room.png" alt="Threads Room" width="638" height="437" /></a></p>
<p>Do ponto de vista do programador, o critical secton é apenas uma estrutura que é usada na chamada de quatro funções básicas: para <a href="http://msdn.microsoft.com/en-us/library/ms683472.aspx" title="InitializeCriticalSection no MSDN">inicializar o recurso</a>, para <a href="http://msdn.microsoft.com/en-us/library/ms682608(VS.85).aspx" title="EnterCriticalSection no MSDN">entrar na seção crítica</a>, para <a href="http://msdn.microsoft.com/en-us/library/ms684169(VS.85).aspx" title="LeaveCriticalSection no MSDN">sair da seção crítica</a> e para <a href="http://msdn.microsoft.com/en-us/library/ms682552(VS.85).aspx" title="DeleteCriticalSection no MSDN">liberar o recurso</a> (quando aquele critical section não mais será usado).</p>
<p>Falando assim, parece simples. Bom, na verdade é simples, mesmo. Tudo que você precisa para corrigir o programa do artigo anterior é criar um critical section e fazer com que as threads obtenham-no antes de mexer com o contador compartilhado.</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
 
<span style="color: #006600;">#define MAX_GLOBAL_COUNTER 10</span>
 
<span style="color: #0000ff;">int</span> g_globalCounter = <span style="color: #000000;">0</span>;
CRITICAL_SECTION g_globalCounterCS;
 
 
DWORD WINAPI IncrementGlobalCounter<span style="color: #000000; font-weight: bold;">&#40;</span>PVOID<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	DWORD tid = GetCurrentThreadId<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
 
	<span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> g_globalCounter &lt; MAX_GLOBAL_COUNTER <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		<span style="color: #006600;">// esse &eacute; o come&ccedil;o de nossa se&ccedil;&atilde;o cr&iacute;tica</span>
		<span style="color: #006600;">// s&oacute; uma thread entra por vez por aqui</span>
		EnterCriticalSection<span style="color: #000000; font-weight: bold;">&#40;</span>&amp;g_globalCounterCS<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
		<span style="color: #0000ff;">int</span> temp = g_globalCounter;
		temp = temp + <span style="color: #000000;">1</span>;
		Sleep<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// vou para o final da fila antes de contar</span>
		g_globalCounter = temp;
&nbsp;
		<span style="color: #006600;">// esse &eacute; o fim de nossa se&ccedil;&atilde;o cr&iacute;tica</span>
		<span style="color: #006600;">// a partir dessa chamada outra thread pode entrar pelo come&ccedil;o</span>
		LeaveCriticalSection<span style="color: #000000; font-weight: bold;">&#40;</span>&amp;g_globalCounterCS<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Counter: %d<span style="color: #666666;">\t</span><span style="color: #666666;">\t</span>Thread: %d<span style="color: #666666;">\n</span>"</span>, temp, tid<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
 
 
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	HANDLE threads<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
	DWORD tids<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
&nbsp;
	<span style="color: #006600;">// precisamos inicializar nosso recurso de se&ccedil;&atilde;o cr&iacute;tica	</span>
	InitializeCriticalSection<span style="color: #000000; font-weight: bold;">&#40;</span>&amp;g_globalCounterCS<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">for</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">int</span> i = <span style="color: #000000;">0</span>; i &lt; <span style="color: #000000;">3</span>; ++i <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		threads<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span> = CreateThread<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000000;">0</span>, IncrementGlobalCounter, <span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, &amp;tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Thread %i: %d<span style="color: #666666;">\n</span>"</span>, i, tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
 
	WaitForMultipleObjects<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span>, threads, <span style="color: #0000ff;">TRUE</span>, INFINITE<span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #006600;">// precisamos liberar o recurso de se&ccedil;&atilde;o cr&iacute;tica</span>
	DeleteCriticalSection<span style="color: #000000; font-weight: bold;">&#40;</span>&amp;g_globalCounterCS<span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;</pre></p>
<h4>Molho de chaves</h4>
<p>Para finalizar, algo para pensar: se uma thread só consegue um critical section depois que outra thread soltá-lo, o que acontece se essa outra thread estiver esperando por outro critical section que uma thread que aguarda estiver segurando?</p>
<p>Acabamos de ilustrar um procedimento muito simples para cagar completamente no código e gerar um travamento que pode demorar de horas a semanas para ser detectado e resolvido. É o conhecido <font color="#ff0000"><strong>deadlock</strong></font>. Se você não entendeu ainda, imagine que, para voltar à sala das threads, a primeira thread que saiu precisa de duas chaves; só que ela só pegou a primeira, e a segunda está dentro da sala. Para pegar a segunda chave, ela precisa entrar na sala, só que a sala está trancada pelas duas chaves!</p>
<p>Deadlocks são sempre indesejáveis, e é por isso que existem diversas técnicas para tentar evitá-los. A mais conhecida é sempre obter os critical sections <strong>na mesma ordem</strong>. Dessa forma a obtenção de recursos é hierarquizada, o que impede que dois CSs estejam no mesmo nível de obtenção, evitando que duas threads distintas os obtenham.</p>
<p>Espero que tenha ficado claro nossa breve explanação de como podemos controlar programas multithreading. Espero, pois a próxima tarefa é entender outros conceitos mais abstratos e virtuais, como funções virtuais e classes abstratas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/a-sala-da-fila-das-threads/feed</wfw:commentRss>
		</item>
		<item>
		<title>Deixe o programador programar</title>
		<link>http://www.caloni.com.br/blog/archives/deixe-o-programador-programar</link>
		<comments>http://www.caloni.com.br/blog/archives/deixe-o-programador-programar#comments</comments>
		<pubDate>Thu, 09 Apr 2009 23:58:19 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/deixe-o-programador-programar</guid>
		<description><![CDATA[ Seis meses se passaram desde que defini o cronograma para um projeto importante (mas não urgente) que deveria ser entregue cinco meses atrás. O tempo em dias que estimei na época não havia mudado nada, mas uma série de desventuras (tarefas brotando do chão e umas férias bem merecidas) fizeram com que quase nenhuma [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/o-tempo-voa.png" title="O Tempo Voa" alt="O Tempo Voa" align="left" height="153" width="162" /> Seis meses se passaram desde que defini o cronograma para um projeto importante (mas não urgente) que deveria ser entregue cinco meses atrás. O tempo em dias que estimei na época não havia mudado nada, mas uma <a href="http://www.imdb.com/title/tt0339291/" title="Desventuras em Série">série de desventuras</a> (tarefas brotando do chão e umas férias bem merecidas) fizeram com que quase nenhuma linha de código tivesse sido produzida para aquele projeto. No entanto, tenho a consciência tranquila, já que estou em uma de minhas fases mais produtivas e inovadoras.</p>
<p>Então eis que surge na porta do templo sagrado (a sala de desenvolvimento) um dos mortais que costuma acreditar que "dirige" seus funcionários. Vira-se para mim e "define" que esse projeto não poderá passar desse mês. E todas aquelas tarefas urgentes que estavam furando a fila de prioridades, como a última da semana passada, devem ser postergadas. É lógico que nada disso foi surpresa, visto que outros discursos desse tipo e outras tarefas urgentes já haviam aparecido no decorrer desses seis meses; mas, enfim, esse foi o primeiro <em>deadline </em>oficialmente<em> </em>definido.</p>
<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/ferias-na-praia.png" title="Férias na Praia" alt="Férias na Praia" align="left" height="152" width="180" /> Por isso mesmo, com uma preocupação constante em minha cabeça, decido desestressar um pouco e ter um almoço bem alargado (quatro horas) em um outro bairro, em outro ambiente, com uns velhos amigos para jogar alguma conversa fora. Nada como a vida fluindo devagar para fazer esquecer detalhes menos essenciais, como trabalho e estresse no trabalho. Sou obrigado nessa hora a parafrasear o sócio mais espirituoso de nossa empresa, que coincidentemente estava presente no almoço: "mas, afinal de contas, quem foi que definiu que a vida tem que ter trabalho e estresse?".</p>
<p>Eu assino embaixo.</p>
<p>Porém, terminado o almoço, volto a pensar em como resolverei o impasse do cronograma do tal projeto superimportante, quando, ao passar pela entrada do metrô, colocam na minha mão justamente um desses panfletos de rua com mensagens subliminares. E nele estava, acreditem, leitores, a solução para todos os meus problemas!</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/santo-expedito.jpg" title="Santo Expedito"><img src="http://www.caloni.com.br/blog/wp-content/uploads/santo-expedito.jpg" alt="Santo Expedito" height="347" width="251" /></a><a href="http://www.caloni.com.br/blog/wp-content/uploads/oracao-santo-expedito.jpg" title="Oração do Santo Expedito"><img src="http://www.caloni.com.br/blog/wp-content/uploads/oracao-santo-expedito.jpg" alt="Oração do Santo Expedito" height="350" width="296" /></a></p>
<blockquote><p><em>Se você está com algum PROBLEMA DE DIFÍCIL SOLUÇÃO e precisa de AJUDA URGENTE, peça esta ajuda a Santo Expedito que é o Santo dos Negócios que precisam de Pronta Solução e cuja invocação nunca é tardia. (Abaixo segue a oração ao Santo).</em></p></blockquote>
<h4>Agradeço a Santo Expedito pela Graça Alcançada</h4>
<p>É lógico que toda essa história fantasiosa pode ser pura ficção com um pingo sequer de realidade, e no fundo almocei foi mesmo é com meus amigos imaginários. No entanto, é capaz que esse não seja um cenário incomum em muitas empresas de tecnologia por aí afora, que insistem em fazer duas coisas que, aliadas, podem gerar qualquer coisa, menos um projeto bem feito e testado:</p>
<p>- Pedir que seus funcionários <strong>elaborem um cronograma</strong> de um projeto complexo (um mês ou mais de trabalho).<br />
- Pedir que seus funcionários <strong>espremam o tempo definido</strong> para o projeto de alguma forma mágica.</p>
<p>O problema é que, na área de informática, apesar de ciência esotérica e cheia de mistérios, não existem santos, não existem milagres e não existe mágica que gere um código de qualidade se não for despendido para ele uma soma considerável de tempo e trabalho. E não estou falando de nenhum luxo. É o tempo justo, mesmo.</p>
<p>Por isso que há eras <a href="http://1bit.com.br/content.1bit/weblog/ambiente" title="Trabalhamos no ambiente correto?">meu amigo Strauss</a> e o <a href="http://brazil.joelonsoftware.com/Articles/PainlessSoftwareSchedules.html" title="Cronogramas">conhecido Joel</a> falam sobre as necessidades básicas de um programador e criticam o resto. As necessidades básicas, na minha opinião, se resumem em três regras de ouro:</p>
<p>1. Dê condições para o programador pensar<br />
2. Dê condições para o programador trabalhar<br />
3. Dê condições para o programador programar</p>
<p>Fora isso, o resto é perfumaria, perda de tempo e enchimento de saco. Os bons programadores não querem ser gerenciados: querem programar. Só isso. Deixe-os com seus problemas e vá tomar conta de algo que não atrapalhe suas vidas. Já estará fazendo um imenso avanço na produtividade de sua empresa.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/deixe-o-programador-programar/feed</wfw:commentRss>
		</item>
		<item>
		<title>A fila das threads</title>
		<link>http://www.caloni.com.br/blog/archives/a-fila-das-threads</link>
		<comments>http://www.caloni.com.br/blog/archives/a-fila-das-threads#comments</comments>
		<pubDate>Tue, 07 Apr 2009 00:41:51 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Código]]></category>

		<category><![CDATA[Sistema Operacional]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/a-fila-das-threads</guid>
		<description><![CDATA[





 Em um ambiente multithreading, diversas threads disputam "a tapas" a atenção do processador (CPU). Certo? Podemos dizer que, em um ambiente com muito processamento a realizar, de certa forma é isso que acontece. São threads e mais threads rodando um pedacinho de código cada vez que passam pelo processador.
Um ambiente complexo como esse é [...]]]></description>
			<content:encoded><![CDATA[





<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/telling-stories.png" title="Telling Stories" alt="Telling Stories" align="left" width="136" height="186" /> Em um ambiente <em>multithreading</em>, diversas threads disputam "a tapas" a atenção do processador (CPU). Certo? Podemos dizer que, em um ambiente com muito processamento a realizar, de certa forma é isso que acontece. São threads e mais threads rodando um <a href="http://www.caloni.com.br/blog/archives/historia-do-windows-parte-40" title="História do Windows explicando agendamento de threads">pedacinho de código</a> cada vez que passam pelo processador.</p>
<p>Um ambiente complexo como esse é repleto de pequenos detalhes que podem fazer o iniciante logo desanimar quando tentar depurar um programa com mais de uma thread. De fato, eu já percebi que muitos não vão saber nem como começar a mastigar o problema.</p>
<p>Por isso mesmo que eu tive que inventar algumas analogias no mínimo interessantes a respeito do assunto. Sem analogias, não sei como falaria sobre essas coisas de forma amena e "explicável".</p>
<p>A primeira "parábola" conta a história da fila das threads em direção ao guichê das CPUs.</p>
<p>O exemplo abaixo cria três threads, todas iniciando na mesma função. O objetivo de todas elas é incrementar um contador até que seu valor chegue a 10. Todas param quando esse objetivo é alcançado.</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #006600;">#define MAX_GLOBAL_COUNTER 10</span>
&nbsp;
<span style="color: #0000ff;">int</span> g_globalCounter = <span style="color: #000000;">0</span>;
&nbsp;
&nbsp;
DWORD WINAPI IncrementGlobalCounter<span style="color: #000000; font-weight: bold;">&#40;</span>PVOID<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	DWORD tid = GetCurrentThreadId<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> g_globalCounter &lt; MAX_GLOBAL_COUNTER <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		<span style="color: #0000ff;">int</span> temp = g_globalCounter;
		temp = temp + <span style="color: #000000;">1</span>;
		g_globalCounter = temp;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Counter: %d<span style="color: #666666;">\t</span><span style="color: #666666;">\t</span>Thread: %d<span style="color: #666666;">\n</span>"</span>, temp, tid<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	HANDLE threads<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
	DWORD tids<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
&nbsp;
	<span style="color: #0000ff;">for</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">int</span> i = <span style="color: #000000;">0</span>; i &lt; <span style="color: #000000;">3</span>; ++i <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		threads<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span> = CreateThread<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000000;">0</span>, IncrementGlobalCounter, <span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, &amp;tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Thread %i: %d<span style="color: #666666;">\n</span>"</span>, i, tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
	WaitForMultipleObjects<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span>, threads, <span style="color: #0000ff;">TRUE</span>, INFINITE<span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<p>Esta é a saída:</p>
<pre>Thread 0: 3508
Thread 1: 1744
Thread 2: 3128
Counter: 1              Thread: 3508
Counter: 2              Thread: 3508
Counter: 3              Thread: 3508
Counter: 4              Thread: 3508
Counter: 5              Thread: 3508
Counter: 6              Thread: 3508
Counter: 7              Thread: 3508
Counter: 8              Thread: 3508
Counter: 9              Thread: 3508
Counter: 10             Thread: 3508</pre>
<p>Pelo jeito, a primeira thread não deu chance para as outras. Isso acontece por causa do <strong>pequeno espaço de tempo que é necessário para realizar a tarefa de incrementar uma variável</strong>. Tempo esse tão pequeno que nem foi suficiente para a primeira thread dar lugar para as outras duas threads e ir para o final da fila.</p>
<h4>A fila das threads</h4>
<p>Quando uma thread quer realizar algum processamento, ela precisa entrar na<strong> fila das threads ativas</strong>, que aguardam pela CPU que irá atendê-las. Nessa fila ela pega uma senha e aguarda a sua vez. Só que cada um que é atendido pela CPU tem um <strong>tempo máximo de atendimento</strong>, que nós chamamos de <a href="http://en.wikipedia.org/wiki/Preemptive_multitasking#Time_slice" title="Multitarefa Preemptivo na Wikipedia">quantum, ou time slice</a>. Se o tempo máximo estoura, ou a thread não tem mais nada pra fazer, ela sai do guichê de atendimento e volta a ficar inativa, ou volta para o final da fila, aguardando por mais processamento.</p>
<p><a href="http://www.caloni.com.br/blog/wp-content/uploads/fila-das-threads.gif" title="Fila das threads"><img src="http://www.caloni.com.br/blog/wp-content/uploads/fila-das-threads.gif" alt="Fila das threads" width="679" height="465" /></a></p>
<p>Uma thread pode opcionalmente ir para o final da fila por conta própria. Para isso, basta que ela chame a função <a href="http://msdn.microsoft.com/en-us/library/ms686298(VS.85).aspx" title="Sleep no MSDN">Sleep</a> da API passando qualquer valor em milissegundos; até mesmo zero. Se passar um valor diferente de zero, ela irá para outra fila de espera, a <strong>fila das inativas</strong>, até o tempo determinado estourar. Depois ela volta para a fila das threads ativas. Se passar zero, ela vai direto para a fila das ativas.</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #006600;">#define MAX_GLOBAL_COUNTER 10</span>
&nbsp;
<span style="color: #0000ff;">int</span> g_globalCounter = <span style="color: #000000;">0</span>;
&nbsp;
&nbsp;
DWORD WINAPI IncrementGlobalCounter<span style="color: #000000; font-weight: bold;">&#40;</span>PVOID<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	DWORD tid = GetCurrentThreadId<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> g_globalCounter &lt; MAX_GLOBAL_COUNTER <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		<span style="color: #0000ff;">int</span> temp = g_globalCounter;
		temp = temp + <span style="color: #000000;">1</span>;
		g_globalCounter = temp;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Counter: %d<span style="color: #666666;">\t</span><span style="color: #666666;">\t</span>Thread: %d<span style="color: #666666;">\n</span>"</span>, temp, tid<span style="color: #000000; font-weight: bold;">&#41;</span>;
		Sleep<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// vou para o final da fila</span>
	<span style="color: #000000; font-weight: bold;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	HANDLE threads<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
	DWORD tids<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
&nbsp;
	<span style="color: #0000ff;">for</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">int</span> i = <span style="color: #000000;">0</span>; i &lt; <span style="color: #000000;">3</span>; ++i <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		threads<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span> = CreateThread<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000000;">0</span>, IncrementGlobalCounter, <span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, &amp;tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Thread %i: %d<span style="color: #666666;">\n</span>"</span>, i, tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
	WaitForMultipleObjects<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span>, threads, <span style="color: #0000ff;">TRUE</span>, INFINITE<span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<pre>Thread 0: 2284
Thread 1: 4080
Thread 2: 3572
Counter: 1              Thread: 2284
Counter: 2              Thread: 4080
Counter: 3              Thread: 3572
Counter: 4              Thread: 2284
Counter: 5              Thread: 4080
Counter: 6              Thread: 3572
Counter: 7              Thread: 2284
Counter: 8              Thread: 4080
Counter: 9              Thread: 3572
Counter: 10             Thread: 2284</pre>
<p>Agora cada thread, depois de incrementar uma vez o contador, volta para o final da fila. Dessa forma vemos uma thread de cada vez incrementando o mesmo contador.</p>
<h4>No próximo capítulo: problemas de sincronismo</h4>
<p>Peraí. O mesmo contador? Isso não pode gerar problemas de duas threads tentando incrementar o <strong>mesmo contador</strong> ao <strong>mesmo tempo</strong>?</p>
<p>Não vou mentir; pode sim. Para isso acontecer, basta <strong>irmos para o final da fila antes de incrementarmos</strong>, mas <strong>após pegarmos o valor atual do contador</strong>. Note que a saída muda completamente.</p>
<p><pre><span style="color: #006600;">#include &lt;windows.h&gt;</span>
<span style="color: #006600;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #006600;">#define MAX_GLOBAL_COUNTER 10</span>
&nbsp;
<span style="color: #0000ff;">int</span> g_globalCounter = <span style="color: #000000;">0</span>;
&nbsp;
&nbsp;
DWORD WINAPI IncrementGlobalCounter<span style="color: #000000; font-weight: bold;">&#40;</span>PVOID<span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	DWORD tid = GetCurrentThreadId<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
&nbsp;
	<span style="color: #0000ff;">while</span><span style="color: #000000; font-weight: bold;">&#40;</span> g_globalCounter &lt; MAX_GLOBAL_COUNTER <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		<span style="color: #0000ff;">int</span> temp = g_globalCounter;
		temp = temp + <span style="color: #000000;">1</span>;
		Sleep<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">0</span><span style="color: #000000; font-weight: bold;">&#41;</span>; <span style="color: #006600;">// vou para o final da fila antes de contar</span>
		g_globalCounter = temp;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Counter: %d<span style="color: #666666;">\t</span><span style="color: #666666;">\t</span>Thread: %d<span style="color: #666666;">\n</span>"</span>, temp, tid<span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #000000;">0</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&#123;</span>
	HANDLE threads<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
	DWORD tids<span style="color: #000000; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&#93;</span>;
&nbsp;
	<span style="color: #0000ff;">for</span><span style="color: #000000; font-weight: bold;">&#40;</span> <span style="color: #0000ff;">int</span> i = <span style="color: #000000;">0</span>; i &lt; <span style="color: #000000;">3</span>; ++i <span style="color: #000000; font-weight: bold;">&#41;</span>
	<span style="color: #000000; font-weight: bold;">&#123;</span>
		threads<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span> = CreateThread<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #0000ff;">NULL</span>, <span style="color: #000000;">0</span>, IncrementGlobalCounter, <span style="color: #000000;">0</span>, <span style="color: #000000;">0</span>, &amp;tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
		<span style="color: #0000ff;">printf</span><span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #666666;">"Thread %i: %d<span style="color: #666666;">\n</span>"</span>, i, tids<span style="color: #000000; font-weight: bold;">&#91;</span>i<span style="color: #000000; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">&#41;</span>;
	<span style="color: #000000; font-weight: bold;">&#125;</span>
&nbsp;
	WaitForMultipleObjects<span style="color: #000000; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span>, threads, <span style="color: #0000ff;">TRUE</span>, INFINITE<span style="color: #000000; font-weight: bold;">&#41;</span>;
<span style="color: #000000; font-weight: bold;">&#125;</span></pre></p>
<pre>Thread 0: 2136
Thread 1: 4024
Thread 2: 2584
Counter: 1              Thread: 2136
Counter: 1              Thread: 4024
Counter: 1              Thread: 2584
Counter: 2              Thread: 2136
Counter: 2              Thread: 4024
Counter: 2              Thread: 2584
Counter: 3              Thread: 2136
Counter: 3              Thread: 4024
Counter: 3              Thread: 2584
Counter: 4              Thread: 2136
Counter: 4              Thread: 4024
Counter: 4              Thread: 2584
Counter: 5              Thread: 2136
Counter: 5              Thread: 4024
Counter: 5              Thread: 2584
Counter: 6              Thread: 2136
Counter: 6              Thread: 4024
Counter: 6              Thread: 2584
Counter: 7              Thread: 2136
Counter: 7              Thread: 4024
Counter: 7              Thread: 2584
Counter: 8              Thread: 2136
Counter: 8              Thread: 4024
Counter: 8              Thread: 2584
Counter: 9              Thread: 2136
Counter: 9              Thread: 4024
Counter: 9              Thread: 2584
Counter: 10             Thread: 2136
Counter: 10             Thread: 4024</pre>
<p>Esse problema ocorre pelo seguinte motivo: quando uma thread guarda o valor do contador na variável temp e volta para o final da fila, ela deixa de armazenar o contador atualizado para apenas depois que todas as outras threads passarem na sua frente. Só que as outras threads também pegam o mesmo valor do contador, pois ele ainda não foi alterado. Quando chega a hora da segunda passada no guichê das CPUs, todas as threads incrementaram o mesmo valor do contador.</p>
<p>O exemplo acima forçou essa situação, mas é preciso lembrar que isso pode acontecer mesmo sem o Sleep. É possível que o tempo da thread se esgote e ela pare de ser atendida  justo na hora que iria salvar a variável temp no contador global. Dessa forma, ela vai para o final da fila à força e, quando voltar a ser atendida, uma outra thread já terá incrementado o mesmo valor.</p>
<p>Esse problema pode ser facilmente resolvido se utilizarmos um <strong>sistema de bloqueio</strong> entre threads do mesmo processo. Uma <a href="http://www.caloni.com.br/blog/archives/a-sala-da-fila-das-threads" title="A sala da fila das threads">outra história</a> para contar da próxima vez.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/a-fila-das-threads/feed</wfw:commentRss>
		</item>
		<item>
		<title>Depurando até o último segundo</title>
		<link>http://www.caloni.com.br/blog/archives/depurando-ate-o-ultimo-segundo</link>
		<comments>http://www.caloni.com.br/blog/archives/depurando-ate-o-ultimo-segundo#comments</comments>
		<pubDate>Tue, 31 Mar 2009 11:16:43 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Depuração]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/depurando-ate-o-ultimo-segundo</guid>
		<description><![CDATA[Como depurar um programa que dá pau logo no final do desligamento de uma máquina?
No cenário em que isso se passa não existem usuários logados no momento, o que significa a impossibilidade de rodar qualquer programa em uma sessão prévia e mantê-lo no ar após o logoff. A não ser que se trate de um [...]]]></description>
			<content:encoded><![CDATA[<p>Como depurar um programa que dá pau logo no final do desligamento de uma máquina?</p>
<p>No cenário em que isso se passa não existem usuários logados no momento, o que significa a impossibilidade de rodar qualquer programa em uma sessão prévia e mantê-lo no ar após o <em>logoff</em>. A não ser que se trate de um <a href="http://en.wikipedia.org/wiki/Windows_service" title="Windows Service na Wikipedia">serviço</a>.</p>
<p>O nosso programa é justamente um serviço, e por isso ele continua rodando até o final, ou bem perto dele. A primeira ideia que vem à mente é instalar o <strong>Msvcmon</strong> - depurador remoto do Visual Studio - como um serviço, como aliás <a href="http://www.caloni.com.br/blog/archives/como-rodar-qualquer-coisa-como-servico" title="Como rodar qualquer coisa como serviço">já foi demonstrado neste blogue</a>.</p>
<p>Essa é uma boa ideia, de fato. Contudo, não podemos esquecer que a ordem de descarregamento dos serviços pode não favorecer o nosso depurador remoto e ele ir embora antes que consigamos "atachar" nosso VC no programa faltoso. Além do mais, a própria rede, que é disponibilizada com a ajuda de serviços, <strong>pode não estar no ar</strong>, mesmo que o Msvcmon esteja.</p>
<p>Tudo bem, vamos dizer que você é um expert em configuração de dependências de serviços e conseguiu fazer com que a rede, o Msvcmon e o programa faltoso sejam os últimos serviços - com exceção dos <em>drivers</em> - a serem descarregados. Bravo!</p>
<p>Contudo, isso não vai adiantar de muita coisa se for necessário parar a execução por um breve momento e analisar a pilha por, digamos,  cinco segundos. Esse é o tempo que o sistema - que continua rodando - precisa para desligar a máquina.</p>
<p>Agora o problema é outro: não há tempo para análise durante a depuração, pois o sistema continua rodando. Nesse caso, teremos que ser mais radicais e <strong>parar o próprio sistema</strong> para que possamos depurar calmamente o problema. Isso implica em termos que utilizar um <strong>depurador de kernel</strong> <a href="http://www.caloni.com.br/blog/archives/aprendendo-rapidamente-conceitos-essenciais-do-windbg" title="Aprendendo rapidamente conceitos do WinDbg">(WinDbg</a>), pois só ele tem poderes de congelar o sistema inteiro.</p>
<p>Mas, ainda assim, precisamos de um <strong>depurador de user</strong> para fazer análises mais profundas ou, pelo menos, mais simples, com a ajuda de símbolos e tudo mais. Nesse caso é necessário usar um depurador de user que <strong>redireciona o controle</strong> para o depurador de kernel. A transição user mode &gt;&gt; kernel mode pode ser feita com apenas <a href="http://www.caloni.com.br/blog/archives/kernel-mode-user-mode" title="User Mode &gt;&gt; Kernel Mode">algumas configurações</a> antes do reboot.</p>
<p>E, após toda essa bagunça, podemos depurar, no conforto de uma VM, o bendito programa matador.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/depurando-ate-o-ultimo-segundo/feed</wfw:commentRss>
		</item>
		<item>
		<title>Provas de conceito&#8230; yes!</title>
		<link>http://www.caloni.com.br/blog/archives/provas-de-conceito-yes</link>
		<comments>http://www.caloni.com.br/blog/archives/provas-de-conceito-yes#comments</comments>
		<pubDate>Thu, 19 Mar 2009 01:24:13 +0000</pubDate>
		<dc:creator>Wanderley Caloni</dc:creator>
		
		<category><![CDATA[Devaneando]]></category>

		<guid isPermaLink="false">http://www.caloni.com.br/blog/archives/provas-de-conceito-yes</guid>
		<description><![CDATA[Uma prova de conceito bem feita segue todos os passos em uma forma micro para entender e provar como as coisas irão funcionar no código de produção: a forma macro.
.
A consequência interessante disso é que, uma vez que a prova de conceito deva ser um miniprojeto das principais partes de um software, desenvolvê-la significa programar [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.caloni.com.br/blog/wp-content/uploads/cientistafeliz.png" title="Cientista Feliz" alt="Cientista Feliz" align="left" height="132" width="137" />Uma <a href="http://en.wikipedia.org/wiki/Proof_of_concept" title="Proof of Concept na Wikipedia">prova de conceito</a> bem feita segue todos os passos em uma <strong>forma micro</strong> para entender e provar como as coisas irão funcionar no código de produção: a <strong>forma macro</strong>.</p>
<p>.</p>
<p>A consequência interessante disso é que, uma vez que a prova de conceito deva ser um <strong>miniprojeto </strong>das principais partes de um software, desenvolvê-la significa <strong>programar todas as partes que realmente importam</strong>, ou seja, centrais para o funcionamento.</p>
<p>.</p>
<p>Portanto, conclui-se que desenvolver provas de conceito é a coisa mais divertida do Universo.</p>
<h4>Para que servem</h4>
<p>Além de serem extremamente divertidas e disputadas entre os programadores, desenvolver provas de conceito gera uma gama de vantagens para o desenvolvimento "sério" do software como um todo, "rodável" e "vendável":</p>
<ul>
<li>Permite <strong>testar as ideias</strong> por trás do software antes de gastar todo o tempo desenvolvendo-o.</li>
<li><strong>Gera conhecimento</strong> para os programadores e para que outros produtos sejam desenvolvidos.</li>
<li>Torna o desenvolvimento algo <strong>ainda mais divertido</strong>, pois tira a parte chata a respeito de comentar código, testar código, mensurar código, rever código, etc.</li>
<li>Consegue tornar o milagre do <a href="http://www.caloni.com.br/blog/archives/cronograma" title="Cronogramas no Caloni.com.br">cronograma realista</a> mais perto do provável.</li>
</ul>
<p>Apenas essas vantagens já praticamente obrigam o profissional do software a pensar em produtos novos em termos de como pode-se testar tudo o que se está dizendo antes de realmente começar a trabalhar pra valer.</p>
<h4>Como fazer</h4>
<p>Mas antes que se pense que fazer provas de conceito não requer nenhuma responsabilidade e que o que você quer ser quando crescer é desenvolvedor de prova de conceito, é necessário colocar alguns pingos nos is antes de continuar. Para criar provas de conceito realmente agregadoras para o projeto, deve-se sempre:</p>
<ul>
<li><strong>Dividir </strong>o software em seus componentes tecnológicos mais críticos e vitais para o sucesso da solução.</li>
<li>Proteger as provas de conceito contra qualquer tipo de preconceito a respeito da tecnologia em questão: <a href="http://www.1bit.com.br/content.1bit/nao_ouca_ninguem" title="Não ouça ninguém!">pese somente os fatos</a>!</li>
<li>Conhecer as <strong>limitações</strong> do software antes mesmo de provar seu funcionamento (por exemplo, não vai funcionar no Windows NT nem a pau).</li>
<li>Garantir que esse conhecimento seja sempre <strong>compartilhado </strong>entre todos do desenvolvimento, pois trata-se de um projeto vazio que formará talvez as bases de um novo produto; se todos conhecerem as bases primeiro, ficará muito mais fácil todos tomarem conta.</li>
</ul>
<p>Por último, deve-se pensar sempre em <strong>todos os programadores da equipe desenvolvendo provas de conceito</strong>. Um doce tão gostoso não pode ser privilégio apenas dos veteranos ou dos acadêmicos chatos, pois torna a vida dos "corregedores" de bugs chata e enfadonha. E <a href="http://www.google.com.br/search?q=pog" title="POG"><em>error prone</em></a>.</p>
<p>Por isso, desde a estagiária até o mocinho bicentenário merecem mexer em código fresco pelo menos uma vez a cada ciclo de desenvolvimento, que terminará com uma versão nova cheia de melhorias que foram testadas em suas respectivas provas de conceito. Provas de conceito que todos tiveram a honra de brincar um pouquinho.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.caloni.com.br/blog/archives/provas-de-conceito-yes/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
