tag:blogger.com,1999:blog-11404152369952237792024-02-02T04:32:50.435-03:00Bruno PospichilEverything about nothing.Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-1140415236995223779.post-42497102548962319882013-01-07T01:13:00.002-02:002016-12-05T10:16:48.622-02:00Rastreamento Kanui - Transportadora TotalExpress<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif; font-size: x-small;">Considerando que o meu texto sobre o rastreamento da B2W fez algum sucesso, decidir ir estendendo com outras lojas conhecidas e suas respectivas transportadoras, hoje é a vez da Kanui.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif; font-size: x-small;">Infelizmente no site deles não consta nenhuma informação sobre a transportadora, porém, pelo menos na minha encomenda, a transportadora escolhida foi a TotalExpress. Para rastrear é bem fácil, basta acessar o site <a href="http://tracking.totalexpress.com.br/tracking/0">http://tracking.totalexpress.com.br/tracking/0</a> e preencher as informações solicitadas.</span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif; font-size: x-small;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: "verdana" , sans-serif; font-size: x-small;">IMPORTANTE: EU NÃO TENHO NENHUMA RELAÇÃO COM A EMPRESA, PORTANTO, NÃO CONSIGO DESCOBRIR O MOTIVO DO SEU PEDIDO ATRASAR. GRATO.</span></div>
Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.comtag:blogger.com,1999:blog-1140415236995223779.post-3475370879019068702012-08-15T03:33:00.002-03:002012-08-15T03:34:47.576-03:00Rastreamento ViaLOG (RBS Zero Hora) Submarino - Americanas <span style="font-family: Verdana, sans-serif; font-size: x-small;">Os usuários de comércio eletrônico sabem como é chato fazer uma compra e não conseguir localizar um rastreamento eficiente, simplesmente para se planejar e aguardar pela encomenda.</span><br />
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><br /></span>
<span style="font-family: Verdana, sans-serif; font-size: x-small;">Ultimamente, sempre que compro da B2W (Submarino e Americanas) as compras têm vindo pela ViaLog, cujo nome oficial é<em style="background-color: white; font-style: normal; font-weight: bold; line-height: 16px;"> RBS</em><span style="background-color: white; color: #222222; line-height: 16px;"> Zero Hora Editora Jornalística S/A. No site da empresa é possível se rastrear, mas pede uma senha, a qual eu nunca tive. Porém, ao ver o destino do mesmo, descobri que é possível localizar suas encomendas somente buscando pelo seu CPF:</span></span><br />
<span style="background-color: white; color: #222222; line-height: 16px;"><span style="font-family: Verdana, sans-serif; font-size: x-small;"><br /></span></span>
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><a href="http://www.ssw.inf.br/2/rastreamento_dest?">http://www.ssw.inf.br/2/rastreamento_dest?</a>
</span><br />
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><br /></span>
<span style="font-family: Verdana, sans-serif; font-size: x-small;">Nessa tela, basta inserir o seu CPF e deixar a senha em branco para que seja possível rastrear todas as suas encomendas que estão sendo entregues por essa transportadora.</span><br />
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><br /></span>
<span style="font-family: Verdana, sans-serif; font-size: x-small;">Espero que ajude algumas pessoas que ficam ansiosas com suas compras online =)</span><br />
<span style="font-family: Verdana, sans-serif; font-size: x-small;"><br /></span>
<span style="font-family: Verdana, sans-serif; font-size: x-small;">Até a próxima.</span>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com13tag:blogger.com,1999:blog-1140415236995223779.post-23109830382372113322012-01-13T23:09:00.001-02:002012-01-13T23:10:16.990-02:00Como fazer túnel SSH com dois saltos (Two hop SSH tunnel)<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Decidi escrever esse texto por ter tido, recentemente, alguma dificuldade para fazer um túnel SSH em uma máquina que estava em uma rede diferente da minha e que somente seria acessível se eu passasse por outras duas máquinas, por não pertencerem todas a mesma rede.</span><br />
<span style="font-size: x-small;"></span><br />
<a name='more'></a></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">No entanto não irei fazer um texto muito explicativo, assumo que conceitos básicos como o funcionamento de túneis SSH sejam entendidos pelo leitor. De qualquer forma segue uma referência:</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"> <b>Usando o PuTTY para túneis SSH:</b> <a href="http://sites.google.com/site/fabiodias/putty">http://sites.google.com/site/fabiodias/putty</a></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">A topologia da algo aproximadamente assim:</span></div>
<div class="separator" style="clear: both; font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6CE1UElHpkFHrk5kvDIlBhpYo8izxQ0BdptA7CZ1maTi-nzXXnd-QdXwaiysoufH79VMAJZyHykjBZAML_Lgu6KkvbB2oTu1-kMYPOKxpr0HxChaMNT9lxrHTVSvBQ2Yc7vlpdIBL5x4d/s1600/Desenho1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6CE1UElHpkFHrk5kvDIlBhpYo8izxQ0BdptA7CZ1maTi-nzXXnd-QdXwaiysoufH79VMAJZyHykjBZAML_Lgu6KkvbB2oTu1-kMYPOKxpr0HxChaMNT9lxrHTVSvBQ2Yc7vlpdIBL5x4d/s400/Desenho1.jpg" width="400" /></a></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: x-small;">Nessa figura temos:</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><b>"host"</b> - Microsoft Windows 7 Professional - PuTTY</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><b>"A"</b>,<b> "B"</b> e<b> "C"</b> - GNU/Linux - Openssh</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Para questão de resumo, o serviço que estamos buscando em <b>"C"</b> é um servidor HTTP, rodando na porta <b>80</b>, A porta utilizada para a criação do túnel em questão será a <b>10080</b>.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Ou seja, do <b>"host"</b> eu somente conseguiria alcançar a máquina <b>"A"</b>, se quisesse atingir ao computador <b>"B"</b> deveria fazer um túnel SSH passando por <b>"A"</b>. Para alcançar <b>"C"</b> esse túnel deveria passar por <b>"A"</b> e <b>"B"</b>.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br />Como devemos passar por duas máquinas, precisaremos de dois túneis: um que atravesse <b>"A"</b> e outro <b>"B"</b>, além disso, esses túneis precisam ter a mesma porta na interconexão entre <b>"A"</b> e <b>"B"</b> (linha azul), se conseguirmos atender essas necessidades, teremos um túnel que irá comunicar "host" diretamente com <b>"C"</b>.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: x-small;">A solução:</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">1) Em <b>"host"</b> criamos uma conexão SSH utilizando o PuTTY para <b>"A"</b>, nessa conexão configuraremos um túnel da seguinte forma:</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Source Port: [<b>10080</b>]; Destination: [<b>localhost:10080</b>], <b>esse é o pulo do gato, nessa instância estamos dizendo que todo o tráfego que sair do "host" na porta 10080 será direcionado para localhost (no caso de "A" na porta 10080);</b></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">2) Nessa sessão SSH que se abriu em <b>"A"</b> (se tudo correu bem nesse momento você terá um acesso ao terminal da máquina) devemos, então criar um outro túnel, dessa vez apontando a porta <b>10080</b> de <b>"A"</b> para a porta <b>80</b> de <b>"C"</b>. Repare que nesse ponto estamos nos conectando em <b>"B"</b>, <b>computador esse que consegue enxergar tanto "A" quanto "C"</b>, ou seja, a configuração de túnel funcionará. Nesse camo estamos em ambiente GNU/Linux, devemos executar o seguinte comando:</span></div>
<div style="font-family: "Courier New",Courier,monospace; text-align: justify;">
<span style="font-size: small;">$ ssh -L 10080:c.dominio.com.br:80 seu_usuario@b.dominio.com.br</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Após efetuar autenticação em <b>"B"</b>, teremos um <b>túnel efetivo entre "host" e "C"</b>, para acessar ao serviço em questão, rodando na porta <b>80</b> de <b>"C"</b>, devemos acessar o endereço <b>localhost:10080 do "host"</b>, e o tráfego será devidamente redirecionado.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;"><br /></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: x-small;">Espero que tenha ficado claro como se cria um túnel de dois saltos, quaisquer dúvidas, podem perguntar pelos comentários.</span></div>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com0tag:blogger.com,1999:blog-1140415236995223779.post-83366564026898108992011-12-14T00:18:00.002-02:002011-12-14T00:21:57.476-02:00Deep C/C++<span style="font-size: x-small;"><span style="font-family: Verdana,sans-serif;">Alguns slides extremamente úteis que falam sobre algumas minúscias dessa poderosa linguagem de programação. Recomendo a leitura.</span></span><br />
<div align="center" id="__ss_9626718" style="width: 550;">
<b style="display: block; margin: 12px 0 4px;"><a href="http://www.slideshare.net/olvemaudal/deep-c" target="_blank" title="Deep C">Deep C</a></b> <iframe frameborder="0" height="450" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/9626718" width="550"></iframe> <br />
<div style="padding: 5px 0 12px;">
View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/olvemaudal" target="_blank">Olve Maudal</a> </div>
</div>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com0tag:blogger.com,1999:blog-1140415236995223779.post-54761934580621515692011-08-18T19:24:00.001-03:002015-05-24T15:01:11.873-03:00Outro blog ou o Site do Google já usa este endereço - O que fazer?<div style="font-family: Verdana,sans-serif; text-align: justify;">
As pessoas que utilizam a plataforma do Blogger muitas vezes querem utilizar domínios personalizados (como o meu bruno.pospichil.com.br) para acessar seus blogs. No entanto é bem comum nos depararmos com o erro: "<span class="wpcpspCSS">Outro blog ou o Site do Google já usa este endereço".</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span class="wpcpspCSS">O que fazer nesse caso? Como identificar o problema e tentar solucioná-lo? Escrevo algumas sugestões:</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span class="wpcpspCSS"></span></div>
<a name='more'></a><div style="font-family: Verdana,sans-serif; text-align: justify;">
O caminho natural a seguir é tentar buscar ajuda no fórum de ajuda do Google (http://www.google.pl/support/forum/p/blogger/) mas é praticamente impossível obter resposta, por isso elaborei alguns outros passos que independem da intervenção do equipe do Google. <br />
Pelo menos para o meu caso, esses passos se mostraram eficientes.<br />
Pode ser que seja necessário executar somente o primeiro, talvez todos, ou talvez nem executando todos eles seja possível registrar seu domínio corretamente, tudo depende do que está causando o problema e, cada caso é um caso.</div>
<ul style="text-align: justify;">
<li><b style="font-family: Verdana,sans-serif;">Verifique se seu DNS está corretamente configurado</b><span style="font-family: Verdana,sans-serif;"> </span></li>
</ul>
<span style="font-family: Verdana,sans-serif;">O primeiro passo, talvez o mais simples é verificar se existe uma entrada "canonical name" (ou simplesmente CNAME) apontando seu endereço para o servidor do Google (ghs.google.com). Para verificar isso, é necessário executar um <a href="http://pt.wikipedia.org/wiki/Nslookup">nslookup</a></span><span style="font-family: Verdana,sans-serif;"> para confirmar sua configuração DNS.</span><br />
<span style="font-family: Verdana,sans-serif;"> Clicando <a href="http://bruno.pospichil.com.br/p/nslookup.html" target="_blank">aqui</a>, </span><span style="font-family: Verdana,sans-serif;">você pode testar os apontamentos, insira seu domínio no campo URL e aperte ok, na saída (no site kloth.net) deve ser exibida uma tabela semelhante a essa:<br />
</span><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuQAMs9nIxJeZIFhLA8nrLTk8KkjXvrtL3cuRQMG23huTQlL4K886Ko1UkuRzwy6XSN-qf05svpfgLPS0NDzPxsjUICjJXcgsdKnjeknQIIIoOQM9mPRuz35ZhzS9iAaVbA_u6EjCoyr_0/s1600/nslookup.png" imageanchor="1" style="font-family: Verdana,sans-serif; margin-left: 1em; margin-right: 1em;"><img border="0" height="127" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuQAMs9nIxJeZIFhLA8nrLTk8KkjXvrtL3cuRQMG23huTQlL4K886Ko1UkuRzwy6XSN-qf05svpfgLPS0NDzPxsjUICjJXcgsdKnjeknQIIIoOQM9mPRuz35ZhzS9iAaVbA_u6EjCoyr_0/s400/nslookup.png" width="400" /> </a><br />
<span style="font-family: Verdana,sans-serif;">Atente para a existência da linha:</span><br />
<b><span style="font-family: Verdana,sans-serif;">seuendereço canonical name = ghs.google.com.</span></b><br />
<span style="font-family: Verdana,sans-serif;">Se houver, seu DNS está corretamente configurado, senão é necessário verificar sua configuração com seu servidor de DNS.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Os passos a seguir pressupõem um cenário (que é bastante possível) em que há um Google Apps </span><span style="font-family: Verdana,sans-serif;">(</span><a href="http://www.google.com/apps/intl/en/group/index.html" style="font-family: Verdana,sans-serif;">http://www.google.com/apps/intl/en/group/index.html</a><span style="font-family: Verdana,sans-serif;">), registrado para seu domínio. O Google Apps requer, para uso de domínios personalizados, a existência de entradas CNAME no seu servidor DNS, assim como o Blogger, essas entradas não podem ser duplicadas (conflitantes).</span><br />
<ul style="text-align: justify;">
<li><b style="font-family: Verdana,sans-serif;">Descubra qual serviço está utilizando seu endereço</b></li>
</ul>
<span style="font-family: Verdana,sans-serif;">Esse passo é um pouco menos exato, muitos dos usuários de domínios personalizados do Blogger utilizam também o Google Apps</span><span style="font-family: Verdana,sans-serif;">, o interessante é que tanto o Blogger quanto o Google Apps utilizam o mesmo servidor (ghs.google.com) para domínios personalizados, por isso, para identificar se algum serviço utiliza seu endereço, após ter o DNS devidamente configurado, tente acessá-lo pelo seu navegador web, caso abra alguma tela do Google ou de algum outro serviço, teremos um indicativo do que é necessário remover para liberar o endereço para o Blogger.</span><br />
<br />
<ul>
<li><b style="font-family: Verdana,sans-serif;">Forçar o Google a atualizar os endereços</b></li>
</ul>
<span style="font-family: Verdana,sans-serif;">Se mesmo assim não foi possível liberar seu domínio para o Blogger, um passo final (e desesperado) e tentar remover todos os serviços do Google Apps que possam ter utilizado sua URL, pode ser Sites, Calendar, algum desses serviços que permitem o uso de endereço customizado. Se não quiser removê-los, muitas vezes somente alterar a URL para a padrão, do Google, já ajuda.</span><br />
<br />
<span style="font-family: Verdana,sans-serif;">Se mesmo assim não for possível configurar seu blog corretamente, coloque a URL como comentário que eu tentarei ajudar.</span>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com47tag:blogger.com,1999:blog-1140415236995223779.post-50197703563880559982011-08-07T04:19:00.005-03:002012-01-11T09:49:54.619-02:00Traduzindo o Windows 7/ Windows 7 SP1 6.1.7601 7600 Home/Home Premium/Professional<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Esse é um passo-a-passo para auxiliar pessoas que compraram computadores ou notebooks no exterior e desejam traduzir seu Windows, mantendo a licença original, ou seja, sem ter que desembolsar e sem apelar para pirataria. Basicamente é um procedimento bem simples, além disso funciona na versão sem SP1 também, desde que sejam utilizados os arquivos adequados.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"></span><br />
<a name='more'></a><br />
<span style="font-size: small;">Outro ponto importante é que esse procedimento utiliza somente aplicativos do próprio Windows e os Pacotes de Línguas (Language Packs) originais da Microsoft.</span><br />
<br />
<b><span style="font-size: small;">IMPORTANTE: Não siga os passos abaixos caso não saiba o que está fazendo, não me responsabilizo por danos causados a sua instalação do Windows.</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">NOTA: Alguns dos passos abaixos dependem de permissão de Administrador, em alguns pontos será solicitada permissão de acesso da UAC (User Access Control), que deve ser concedida.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Esse tutorial foi testado em um notebook HP, com Windows 7 SP1 (6.1.7601) Home Premium, em inglês.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;">Passo 1 - Obter Language Pack (LP) adequado ao seu sistema:</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">SP1 (Build 7601) x86: <a href="http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.1-kb2483139-x86-pt-br_6e1d337b2fd56669d461e82601aa51004fecbd24.exe">http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.1-kb2483139-x86-pt-br_6e1d337b2fd56669d461e82601aa51004fecbd24.exe</a></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">SP1 (Build 7601) x64: <a href="http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.1-kb2483139-x64-pt-br_f8035731c55d774c95c7c673aedfd42d52479294.exe">http://download.windowsupdate.com/msdownload/update/software/updt/2011/02/windows6.1-kb2483139-x64-pt-br_f8035731c55d774c95c7c673aedfd42d52479294.exe</a></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">não-SP1 (Build 7600) x86: <a href="http://download.windowsupdate.com/msdownload/update/software/updt/2009/08/windows6.1-kb972813-x86-pt-br_0a3fe79820d6d199dd43495d4efa5c40f270e45a.exe">http://download.windowsupdate.com/msdownload/update/software/updt/2009/08/windows6.1-kb972813-x86-pt-br_0a3fe79820d6d199dd43495d4efa5c40f270e45a.exe</a><a href="http://www.megaupload.com/?d=HKHHCBU0"></a></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">não-SP1 (Build 7600) x64: <a href="http://download.windowsupdate.com/msdownload/update/software/updt/2009/08/windows6.1-kb972813-x64-pt-br_276b65f3b6b2657c8fe936f9841dc1243e02dc7b.exe">http://download.windowsupdate.com/msdownload/update/software/updt/2009/08/windows6.1-kb972813-x64-pt-br_276b65f3b6b2657c8fe936f9841dc1243e02dc7b.exe</a></span><br />
<br />
<span style="font-size: small;">Editado em 11/01/2012 - 09:49 - Adicionados novos links para download do language pack. </span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;">Passo 2 - Extrair lp.cab</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Após obter o LP, é necessário extrair o lp.cab, o problema é que o instalador deleta automaticamente o arquivo quando verifica que a versão não é a Ultimate.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Nesse caso, o processo é o seguinte: Dê um duplo clique no .exe do LP baixado no passo 1, será criado um arquivo lp.cab no mesmo diretório do executável, assim que o arquivo aparecer, dê um duplo clique nele, para abrí-lo, isso irá impedir que o executável o delete. Após a finalização do executável, terá o arquivo disponível.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;">Passo 3 - Instalar o Language Pack</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Execute um prompt de comando como admnistrador:</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Opção 1: Ir ao atalho do Prompt de Comando, no Menu Iniciar, clicar com o botão direito e selecionar "Run as administrator".</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Opção 2: No Menu Iniciar, no campo "Search Programs and Files" digitar "<span style="font-family: "Courier New",Courier,monospace;">cmd</span>" (sem aspas) e apertar Ctrl + Shift + Enter.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Se o título do Prompt de Comando que abriu contiver a palavra 'Administrator', seu prompt é de administrador.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">No prompt de comando digite:</span></div>
<div style="background-color: black; color: white; font-family: "Courier New",Courier,monospace; text-align: justify;">
<span style="font-size: small;">dism /online /add-package /packagepath:X:\caminho\para\lp.cab</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Alterando X:\caminho\para\lp.cab pelo caminho onde está o lp.cab extraido no passo 2. </span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"> Aguarde até que o processo seja concluído, isso irá demorar alguns minutos.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Após isso, vamos atualizar as telas de entrada e encerramento do Windows, ainda no prompt digite:</span></div>
<div style="background-color: black; color: white; font-family: "Courier New",Courier,monospace; text-align: justify;">
<span style="font-size: small;">bcdedit /set {current} locale pt-BR</span></div>
<div style="background-color: black; color: white; font-family: "Courier New",Courier,monospace; text-align: justify;">
<span style="font-size: small;">bcdboot %WinDir% /l pt-BR </span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;"> Passo 4 - Atualizar o registro:</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Após instalado, agora devemos atualizar o registro do Windows para apontar para o idioma adequado:</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Abra o "regedit";</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Navegue até a chave: <span style="font-family: "Courier New",Courier,monospace;">HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\MUI\UILanguages\</span></span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Verifique se nesse local existe a chave <b>pt-BR</b> bem como a <b>en-US</b>, caso positivo, remova a entrada <b>en-US</b>.</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;">Passo 5 - Reinicie o computador e aproveite seu Windows falando português.</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<br /></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<b><span style="font-size: small;">Passo 6 (opcional) - Ajustar opções regionais</span></b></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Caso queira, ainda pode arrumar as opções de Moeda, Data, Hora, para os padrões utilizados em solo brasileiro, para isso vá para as Opções de Região e Idioma, no Painel de Controle (ou Iniciar -> Executar -> <span style="font-family: "Courier New",Courier,monospace;">intl.cab</span>).</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;">Nessa tela ajuste o Formato para Português (Brasil)</span></div>
<div style="font-family: Verdana,sans-serif; text-align: justify;">
<span style="font-size: small;"><br />
</span></div>
<div style="text-align: justify;">
<span style="font-family: Trebuchet MS;"><span style="font-family: Verdana,sans-serif; font-size: small;">Pronto, agora todas as opções estão como se seu Windows tivesse nascido Brasileiro.</span></span></div>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com74tag:blogger.com,1999:blog-1140415236995223779.post-35746518882227741652011-08-04T02:33:00.006-03:002011-08-04T02:39:23.158-03:00Análise da linguagem Go para programação paralela<div style="font-family: Verdana,sans-serif; text-align: justify;"><div style="text-align: justify;"><span style="font-size: small;"><span style="color: #666666;">Esse texto foi um trabalho acadêmico que escrevi no início de 2010, como uma referência básica sobre o uso da linguagem de programação Go (http://golang.org/) para programação paralela. Ele explica basicamente como se preparar um ambiente para desenvolvimento utilizando-se a linguagem Go e analisa superficialmente os mecanismos existentes para programação paralela.</span></span><br />
</div><span style="font-size: small;"><span style="color: #666666;"></span></span><br />
<a name='more'></a><span style="font-size: small;"><span style="color: #666666;"> </span></span></div><div style="font-family: Verdana,sans-serif;"></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><b>1. Introdução</b></span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">No ano passado o Google anunciou sua própria linguagem de programação, a Go. Segundo seu lançamento a linguagem foi lançada partindo da frustração das linguagens de programação atuais, que acabavam onerando segurança ou desempenho. Buscou-se então uma linguagem que tivesse a facilidade de uma linguagem interpretada com a eficiência de uma linguagem compilada, nisso nasceu a Go. Uma das características bastante faladas é quanto à programação concorrente, mencionando que a linguagem torna muito mais fácil e seguro a construção de programas concorrentes, nesse trabalho irei verificar se isso é realmente verdade.<br />
Cabe ressaltar que nesse trabalho não será abordado o processo de programação em Go como um todo, ou seja, será assumido que o leitor tem conhecimentos sobre as funções básicas da linguagem, além disso, em alguns momentos é feito um paralelo com as POSIX threads, portanto é importante também que o leitor tenha conhecimento no assunto.<b><br />
</b></span></div><div style="font-family: Verdana,sans-serif;"><br />
</div><div style="font-family: Verdana,sans-serif;"><b><span style="font-size: small;">2. Instruções de instalação e uso</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Primeiramente, seguem informações básicas do ambiente inicial, o sistema operacional utilizado foi o GNU/Linux Debian 5.0.4 64 bits (Kernel 2.6.26-2-amd64). Alguns programas são necessários durante a compilação Go, para verificar a existência deles, foram executados os seguintes comandos:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace;"><span style="font-size: small;">$ which gcc</span><br />
<span style="font-size: small;"> $ which make<br />
$ which bison<br />
$ which python<br />
$ which hg #Mercurial</span></div><div style="font-family: "Courier New",Courier,monospace;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Para todos os pacotes deve ter retornado o path do binário solicitado, caso contrário, deve ser instalado utilizando-se a ferramenta de gerenciamento de pacotes da distribuição, no caso do Debian, o apt-get. Dos programas requeridos, o mais incomum é o Mercurial que é um programa de controle de versão, assim como o cvs ou o Subversion.<br />
Após assegurar a presença dos requisitos, é necessário definir algumas variáveis de ambiente, indicando o sistema operacional e a arquitetura utilizada, bem como o diretório em que será baixado o compilador, no meu caso, foram utilizados os seguintes comandos:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">$ export GOOS=Linux</span><br style="color: #6aa84f; font-family: "Courier New",Courier,monospace;" /><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">$ export GOARCH=amd64</span><br style="color: #6aa84f; font-family: "Courier New",Courier,monospace;" /><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">$ export GOROOT=$HOME/go</span></span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Em seguida se deve efetuar o download do código fonte do Go utilizando-se o Mercurial:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT</span></span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Deve-se criar o diretório para abrigar os binários:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">$ mkdir ~/bin</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Nesse ponto estamos aptos a invocar o compilador para gerar os binários da Go, no entanto, ao analisar os scripts de compilação, identifica-se que eles esperam encontrar o programa gmake, ao invés do make, para evitar ter de alterar os scripts, gera-se um link simbólico fazendo com que ao se invocar o gmake, na verdade seja executado o make:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;"># ln -s /usr/bin/make /usr/bin/gmake</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Agora sim, o ambiente está pronto, pode-se chamar o script de compilação:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">$ cd $GOROOT/src </span></div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">$ ./all.bash</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Após o processo de compilação, se tudo correr bem, deve ser exibida a seguinte mensagem:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">N known bugs; 0 unexpected bugs</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Sendo N igual a zero ou um número natural que varia de release para release. Após isso, basta ajustar as variáveis de ambiente ou definir links a seu gosto, pois o compilador já está pronto no diretório bin criado na Tabela 4.</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Como a arquitetura utilizada é 64 bits, foram gerados os binários compatíveis:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"></div><ul style="font-family: Verdana,sans-serif; text-align: justify;"><li><span style="font-size: small;">6g : compilador</span></li>
<li><span style="font-size: small;">6l : linker</span></li>
<li><span style="font-size: small;">Outros, menos importantes agora.</span></li>
</ul><div style="text-align: justify;"><span style="font-family: Verdana,sans-serif; font-size: small;">O 6 no inicio dos binários indicam que eles foram compilados para 64-bits (amd64, x86_64). Se fossem compilados para 32-bits (x86), os binários seriam 8g e 8l.</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">3. Goroutines</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Goroutines são, a grosso modo, threads. Basicamente são funções que são executadas em paralelo com outras goroutines no mesmo espaço de endereçamento. O processo de implementação é relativamente simples: implementa-se a função, normalmente, e no momento de chamá-la, se utiliza a palavra reservada <span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">go</span>, isso faz com que a função seja executada em paralelo com a main ou com outras goroutines que estão sendo executadas ao mesmo tempo.<br />
Um dos mecanismos não encontrados diretamente é a função <b>pthread_join</b>, que é utilizada na sincronização entre threads, fazendo com que uma thread espere por outra, na ausência desse sistema, sugere-se a utilização de um canal binário (será abordado em seguida) para bloquear uma goroutine até que outra sinalize. Isso permite com que o programador defina que o programa só termine quando todas as threads forem concluídas. </span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">4. Mecanismos de programação concorrente</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">A linguagem de programação Go teve desde sua criação a idéia de que a programação concorrente é complicada devido a complexidade no design de softwares concorrentes, como, por exemplo, as POSIX Threads, além de que o desenvolvimento utilizando programação concorrente enfatiza exageradamente o baixo-nível, com mutexes, variáveis de condição e barreiras de memória. Por isso, a Go utiliza mecanismos de mais alto-nível, baseados, principalmente, nos <a href="http://www.usingcsp.com/cspbook.pdf"><i>Communicating Sequential Processes</i></a> de C.A.R. Hoare. Considerando isso, o mecanismo de programação concorrente mais utilizado pela Go considera a utilização de canais para a comunicação entre Goroutines.<br />
No entanto, isso não impede que existam mecanismos tradicionais (“de baixo-nível”) para sincronização, por exemplo, a Go implementa mutexes, por meio da package sync. Mais detalhes serão passados em cada mecanismo, individualmente. </span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">4.1. Canais</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">O mecanismo de alto nível utilizado pela Go são os canais, pode se dizer que canais são buffers compartilhados que garantem a comunicação entre processos com sincronização, garantindo que duas goroutines estão em um estado conhecido.<br />
Existem dois tipos de canais, cada um podendo receber dados de um determinado tipo (int, char, bool, etc), unbuffered e buffered. O unbuffered só permite a inserção de novos termos assim que o anterior for removido, ou seja, não possui buffer, já o buffered possui um espaço de buffer determinado, no exemplo abaixo o buffer possui nove posições.</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">var cj = make(chan int,9) // com buffer de 9 posições de inteiros<br />
var ce = make(chan bool) // unbuffered, de variáveis booleanas</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Por exemplo, no caso citado em aula do produtor-consumidor, a utilização de um canal compartilhado entre os processos garante que algumas situações sejam devidamente cobertas, são elas:</span></div><ul style="font-family: Verdana,sans-serif; text-align: justify;"><li><span style="font-size: small;">Consumidor com buffer vazio: a goroutine fica bloqueada até que seja inserido algum elemento no canal;</span></li>
<li><span style="font-size: small;">Produtor com buffer cheio: a goroutine fica bloqueada até que seja consumido algum elemento do canal.</span></li>
</ul><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Os demais casos não são excepcionais e as rotinas permanecem sincronizadas naturalmente.<br />
Além disso, os canais possuem comportamento FIFO, ou seja, os dados são lidos na mesma ordem que foram inseridos.<br />
Os canais possuem dois operadores básicos, para inserção e remoção de dados no canal. Ambos são representados pelo operador <- com a diferença de que o operador de inserção é binário e o de remoção é unário. Abaixo exemplos de utilização:</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="color: #6aa84f; font-family: "Courier New",Courier,monospace; text-align: justify;"><span style="font-size: small;">cj <- x // insere o elemento x no buffer cj<br />
<-cj // remove o primeiro elemento do buffer ch</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Para ilustrar o comportamento dos canais, foi codificado um exemplo, transcrito abaixo, com alguns comentários, os trechos em vermelho são operações relativas ao controle da seção crítica:</span></div><div style="color: #6aa84f; font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">package main</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">import (</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> "fmt"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">"time"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">"rand"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var end = make(chan bool) /* faz as vezes da pthread_join */</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="color: red; font-family: "Courier New",Courier,monospace;">var buffer = make(chan int,9) /* buffer compartilhado */</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">var cont int</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">func producer() {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">for {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">time.Sleep(rand.Int63()%5e9) /* espera de até 5 segundos */</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">x := rand.Int()%100 /* valor a ser inserido no buffer */</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">fmt.Println(cont, "prod....",x)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">cont++</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="color: red; font-family: "Courier New",Courier,monospace;">buffer <- x</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">end <- true</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">func consumer() {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">for {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">time.Sleep(rand.Int63()%5e9)</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="color: red; font-family: "Courier New",Courier,monospace;">x := <-buffer</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">fmt.Println(cont, "cons....", x);</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">cont--</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">end <- true</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">}</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;">func main() {</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">go producer();</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;">go consumer();</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></span></span><span style="color: #6aa84f; font-size: small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><span style="font-size: small;"><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;"><-end</span><br style="color: #6aa84f; font-family: "Courier New",Courier,monospace;" /><span style="color: #6aa84f; font-family: "Courier New",Courier,monospace;">}</span></span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><br />
</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Logo, podemos concluir que os canais são os mecanismos mais usuais para garantir a seção crítica em Go, além disso, eles implementam uma série de mecanismos de comunicação entre funções.</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">4.2. Mutexes</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Um mecanismo clássico implementado na Go são os mutexes, apesar de seu uso não ser recomendado, sendo substituídos por canais, podemos verificar a sua existência. Os mutexes são definidas na package sync e são divididos em dois tipos: sync.Mutex e sync.RWMutex, ambos possuem primitivas de lock e unlock, com a diferença de que o último prevê primitivas separadas para lock e unlock de leitura e gravação.<br />
Conforme citado anteriormente, o uso de mutexes não é recomendado, tendo em vista que normalmente o uso de canais prevê os bloqueios/desbloqueios necessários em uma determinada operação. </span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">4.3. Semáforos</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Existem algumas primitivas de semáforos implementadas no package runtime, Semacquire e Semrelease, no entanto não consegui encontrar documentação explícita da declaração de semáforos, ao que tudo indica, esses métodos são utilizados na implementação dos canais, mas creio ser possível, de alguma maneira declarar um semáforo. </span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">4.4. Monitores</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;">Não foram encontradas informações sobre a presença de monitores na Go.</span></div><div style="text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><b><span style="font-size: small;">5. Conclusões</span></b></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"> Foi possível verificar que a Go prevê um mecanismo diferenciado para comunicação entre rotinas (“threads”), esse mecanismo facilita bastante a programação tendo em vista que ele remove do programador uma série de responsabilidades e validações. No exemplo do produtor-consumidor pode-se verificar que as operações de controle foram minimizadas pois toda a validação é definida na implementação dos canais.</span></div><div style="font-family: Verdana,sans-serif; text-align: justify;"><br />
</div><div style="font-family: Verdana,sans-serif; text-align: justify;"><span style="font-size: small;"><a href="https://docs.google.com/viewer?a=v&pid=explorer&chrome=true&srcid=0B0AgjKTEvFEhMjI2ODBhMjgtYzg0NS00MzUxLWI3OTEtZWJlZWUzMmZjMjFk&hl=en_US">Download do arquivo original em pdf.</a></span></div><div style="font-family: Verdana,sans-serif;"><span style="font-size: small;"><br />
</span></div>Bruno Pospichilhttp://www.blogger.com/profile/16869797055981265577noreply@blogger.com1