<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Darshan’s Weblog</title>
	<atom:link href="http://www.thedarshan.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thedarshan.com</link>
	<description>“Spero di non incrementare inutilmente l’entropia dell’universo”</description>
	<lastBuildDate>Wed, 22 Feb 2012 23:09:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Implementazione dinamica di una funzione definita ricorsivamente</title>
		<link>http://www.thedarshan.com/informatica/implementazione-dinamica-di-una-funzione-definita-ricorsivamente/</link>
		<comments>http://www.thedarshan.com/informatica/implementazione-dinamica-di-una-funzione-definita-ricorsivamente/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 22:01:26 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[algoritmica]]></category>
		<category><![CDATA[iterativo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[semplice]]></category>
		<category><![CDATA[unipa]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=942</guid>
		<description><![CDATA[Implementazione dinamica di una funzione definita ricorsivamente (Appello Aprile 2010) Sia data la funzione F così definita : Si richiede di implementare in linguaggio C: Una funzione Fr che calcoli F (n, k); Una funzione Frd che calcoli F (n, k) in O(n2 ); Implementazione ricorsiva La fuzione viene implementata applicando semplicemente la formula di &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/implementazione-dinamica-di-una-funzione-definita-ricorsivamente/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>Implementazione dinamica di una funzione definita ricorsivamente (Appello Aprile 2010)</h1>
<p>Sia data la funzione F così definita :</p>
<p><a href="http://www.thedarshan.com/wp-content/uploads/2012/02/Aprile2010_html_748e8883.png"><img class="alignleft size-full wp-image-943" title="Aprile2010_html_748e8883" src="http://www.thedarshan.com/wp-content/uploads/2012/02/Aprile2010_html_748e8883.png" alt="" width="488" height="56" /></a></p>
<p>Si richiede di implementare in linguaggio C:</p>
<ul>
<li>Una funzione Fr che calcoli F (n, k);</li>
<li>Una funzione Frd che calcoli F (n, k) in O(n2 );</li>
</ul>
<h2>Implementazione ricorsiva</h2>
<pre class="brush: cpp; title: ; notranslate">
int F(int n, int k)
{
    if(n*k==0)return n+k;
    return F(n,k-1)+ F(n-1,k)+ F(n-1,k-1);
}
</pre>
<p>La fuzione viene implementata applicando semplicemente la formula di ricorsione</p>
<h2>Implementazione iterativa</h2>
<pre class="brush: cpp; title: ; notranslate">
int Fi(int n, int k)
{
    int **v=malloc(sizeof(int)*(n+1)*(k+1));
    int x=Fi_implementation(n,k,n+1,k+1,v);
    free(v);
    return x;
}

int Fi_implementation(int n, int k, int a, int b,int v[a][b])
{
    int r,c,x;

    for(r=0; r&lt;=n; r++)
    {
        for(c=0; c&lt;=k; c++)
        {
            if(r*c==0)v[r]1=r+c;
            else
                v[r]1=v[r]1+v[r-1]1+v[r-1]1;
        }
    }
    x=v[n][k];
    return v[n][k];
}
</pre>
<p>Il calcolo di ogni elemento n,k richiede il calcolo di tutti gli elementi y&lt;n , n&lt;k e questi elementi vengono usati più di una da tutti gli elementi superiori e a destra, salvandoli in una matrice è possibile ridurre la complessità a O(n*k) occupando O(n*k) memoria.<br />
per facilitare la leggibilità del codice si usa una funzione di appoggio che permette di definire il vettore con le sue dimensioni, altrimenti passando semplicemente un puntatore doppio si dovrebbero calcolare gli indirizzamenti esplicitamente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/implementazione-dinamica-di-una-funzione-definita-ricorsivamente/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Contare le coppie adiacenti in una sequenza in tempo nLog(n)</title>
		<link>http://www.thedarshan.com/informatica/contare-le-coppie-adiacenti-in-una-sequenza-in-tempo-nlogn/</link>
		<comments>http://www.thedarshan.com/informatica/contare-le-coppie-adiacenti-in-una-sequenza-in-tempo-nlogn/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 22:01:45 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[algoritmica]]></category>
		<category><![CDATA[algoritmo]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[ricorsivo]]></category>
		<category><![CDATA[semplice]]></category>
		<category><![CDATA[sequenze]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=938</guid>
		<description><![CDATA[Contare le coppie adiacenti in una sequenza in tempo nLog(n) (Appello Settembre 2010) il testo recita: Sia data una sequenza di interi a1 , a2 , . . . , an . Diciamo che la sequenza contiene una coppia di numeri consecutivi se esistono due interi ai e aj tali che ai = aj + &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/contare-le-coppie-adiacenti-in-una-sequenza-in-tempo-nlogn/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>Contare le coppie adiacenti in una sequenza in tempo nLog(n) (Appello Settembre 2010)</h1>
<p>il testo recita:</p>
<blockquote><p>Sia data una sequenza di interi a1 , a2 , . . . , an . Diciamo che la sequenza contiene una coppia di numeri consecutivi se esistono due interi ai e aj tali che ai = aj + 1. Implementare un algoritmo per contare il numero di coppie consecutive contenute nella sequenza, che impieghi una complessità di tempo complessiva di n log n e una quantità di memoria aggiuntiva di O(n).</p></blockquote>
<h2>Implementazione attraverso un albero binario</h2>
<p>Il problema può essere risolto implementando una treesort e facendo in modo che in fase di inserimento si verifichi l&#8217;esistenza delle coppie adiacenti</p>
<pre class="brush: cpp; title: ; notranslate">
#define N 10
#include &quot;util.h&quot;
#include &quot;strutture.h&quot;
#include &lt;string.h&gt;  // NULL è definito qui

int piazza(nodo *base, nodo *nodo, int coppie){
    int x=nodo-&gt;val-base-&gt;val;
    if(x==1 || x==-1){//ho trovato una coppia
        coppie++;
        printf(&quot;coppia %d &lt;-&gt; %d (%d) \n&quot;,nodo-&gt;val,base-&gt;val, coppie);
    }
    if(x&gt;0){//maggiore, vado a destra
        if(base-&gt;r==NULL){//è vuoto, lo piazzo
            base-&gt;r=nodo;
        }else{//non è vuoto, richiamo
            coppie=piazza(base-&gt;r, nodo, coppie);
        }
    }else{//è minore, vado a sinistra
        if(base-&gt;l==NULL){//è vuoto, lo piazzo
            base-&gt;l=nodo;
        }else{//non è vuoto, richiamo
            coppie=piazza(base-&gt;l, nodo, coppie);
        }
    }
    return coppie;
}

void trovacoppie(int len, int v[len])
{
    int coppie=0,n;
    nodo *nodi=malloc(sizeof(nodo)*len);

    for(n=0; n&lt;len; n++)
    {
        nodi[n].val=v[n];
        nodi[n].l=NULL;
        nodi[n].r=NULL;
        if(n&gt;0)coppie=piazza(nodi, &amp;nodi[n], coppie);
    }
    free(nodi);
    printf(&quot;Un totale di %d coppie trovate\n&quot;, coppie);
}
</pre>
<p>Il contatore delle coppie viene passato a ogni chiamata ricorsiva e viene ritornato in output dalla funzione di ordinamento, in questo modo l&#8217;output finale conterrà il conto totale, questo approccio ha complessità O(n*log(n)) , non possono esistere soluzioni con un ordine di complessità minore inquanto non esistono ordinamenti più veloci essendo n*log(n) la dimensione dell&#8217;albero generato dalle decisioni necessarie per un ordinamento.<br />
L&#8217;albero viene allocato dentro un vettore per facilitarne la deallocazione.</p>
<p style="text-align: center;"><a href="http://www.thedarshan.com/wp-content/uploads/2012/02/AlberoCoppie1.png"><img class="aligncenter size-full wp-image-954" title="AlberoCoppie" src="http://www.thedarshan.com/wp-content/uploads/2012/02/AlberoCoppie1.png" alt="" width="480" height="497" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/contare-le-coppie-adiacenti-in-una-sequenza-in-tempo-nlogn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Determinare la lunghezza della più lunga sottostringa palindroma</title>
		<link>http://www.thedarshan.com/informatica/massima-sottostringa/</link>
		<comments>http://www.thedarshan.com/informatica/massima-sottostringa/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 08:00:42 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[algoritmi numerici]]></category>
		<category><![CDATA[algoritmica]]></category>
		<category><![CDATA[iterativo]]></category>
		<category><![CDATA[palindrome]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[semplice]]></category>
		<category><![CDATA[unipa]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=924</guid>
		<description><![CDATA[Determinare la lunghezza della più lunga sottostringa palindroma ( Appello Aprile 2010) Il testo recita: Data una stringa S = a1 a2 . . . an di n caratteri, si propone il problema di determinare la lunghezza della più lunga palindroma sottostringa di S. Suggerimento: per la risoluzione: Sia l[i, j] la lunghezza della più &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/massima-sottostringa/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>Determinare la lunghezza della più lunga sottostringa palindroma ( Appello Aprile 2010)</h1>
<blockquote><p>Il testo recita:</p>
<p>Data una stringa S = a1 a2 . . . an di n caratteri, si propone il problema di determinare la lunghezza della più lunga palindroma sottostringa di S.</p>
<p><strong>Suggerimento: </strong></p>
<p>per la risoluzione: Sia l[i, j] la lunghezza della più lunga palindroma contenuta nella stringa S[i . . . j] = ai ai+1 . . . aj . Il caso base consiste in una stringa di 0 caratteri, cioè il caso in cui i &gt; j. Altrimenti se i caratteri S[i] ed S[j] sono uguali allora posso controllare se la stringa S[i + 1 . . . j − 1] e palindroma ed eventualmente aggiungere i due caratteri S[i] ed S[j]. In tutti gli altri casi devo risolvere ricorsivamente i problemi l[i + 1, j] e l[i, j − 1] e prendere il massimo. La definizione ricorsiva di una soluzione ottima potrebbe essere così definita
</p></blockquote>
<p style="text-align: center;"><a href="http://www.thedarshan.com/wp-content/uploads/2012/02/Aprile2010_2_html_121ea231.png"><img class="size-full wp-image-925 aligncenter" title="Aprile2010_2_html_121ea231" src="http://www.thedarshan.com/wp-content/uploads/2012/02/Aprile2010_2_html_121ea231.png" alt="" width="470" height="68" /></a></p>
<blockquote><p>
La risoluzione del problema mediante l’utilizzo della programmazione dinamica prevede quindi la costruzione di una tabella di dimensione n × n.Si richiede di implementare in linguaggio C:</p>
<ol>
<li>a) Una funzione lr che calcoli l[1, n] ossia la lunghezza della piùlunga palindroma contenuta nell’intera stringa ;</li>
<li>b) Una funzione lrd che calcoli l[n, k] in O(n2 );</li>
</ol>
</blockquote>
<h2>Implementazione Ricorsiva</h2>
<pre class="brush: cpp; title: ; notranslate">
int m(char s[], int da, int a)
{
    int x;
    if(da&gt;a)return 0;
    if(da==a)return 1;
    if (s[a]==s[da]){
        x=m(s,da+1, a-1);
        if(x==a-da-1)return x+2;
    }
    int r=m(s,da+1,a);
    int l=m(s,da,a-1);
    x=r-l;
    if(x&gt;0)
        return r;
    else
        return l;
}
</pre>
<p>La fuzione viene implementata applicando semplicemente la formula di ricorsione</p>
<h2>Implementazione dinamica</h2>
<pre class="brush: cpp; title: ; notranslate">
int m_d(char s[], int da, int a,int n,int k, int v[n][k])
{
    int x;
    if(da&gt;a)return 0;
    if(da==a)return 1;
    if (s[a]==s[da]){
        x=v[da+1][a-1];
        if(x==a-da-1)return x+2;
    }
    int r=v[da+1][a];
    int l=v[da][a-1];
    x=r-l;
    if(x&gt;0)
        return r;
    else
        return l;
}

int m_iterativa(char stringa[])
{
    int len=strlen(stringa);
    int **v=malloc(sizeof(int)*len*len);
    int i,j;
    for(i=0;i&lt;len;i++){
        for(j=0;j&lt;(len-i);j++){
            int pal=m_d(stringa,j,i+j,len,len,v);
            v[j*len+(i+j)]=pal;
        }
    }
    len=v[len-1];
    free(v);
    return len;
}
</pre>
<p style="text-align: left;">L&#8217;implementazione dinamica viene creata modificando la funzione ricorsiva in modo che i valori già calcolati vengano letti da una matrice invece che ricalcolati. I valori per cui c&lt;r (quelli sopra la diagonale principale) sono necessariamente 0 e non vanno calcolati.</p>
<p style="text-align: center;">
<em>L&#8217;unico modo di percorrere la matrice senza creare dipendenze da valori non ancora calcolati è per diagonali.</em></p>
<p style="text-align: left;">
Esempi di matrici dei valori parziali</p>
<p><TABLE WIDTH=100% BORDER=0 CELLPADDING=4 CELLSPACING=0><br />
	<COL WIDTH=85*><br />
	<COL WIDTH=171*><br />
	<TR VALIGN=TOP><br />
		<TD WIDTH=33% HEIGHT=230><br />
			<br />
			[ 0   0   0   0   0   0   1   ] <br />
			[ 0   0   0   0   0   1   1   ] <br />
			[ 0   0   0   0   1   1   1   ] <br />
			[ 0   0   0   1   1   1   1   ] <br />
			[ 0   0   1   1   3   3   3   ] <br />
			[ 0   1   1   1   3   5   5   ] <br />
			[ 1   1   1   1   3   5 <B>5</B> ] <br />
			pabcbaq -&gt;	5<br />
		</TD><br />
		<TD WIDTH=67%><br />
			[ 0   0   0   0   0   0   0   0   0   0   0   0   1   ] <br />
			[ 0   0   0   0   0   0   0   0   0   0   0   1   1   ] <br />
			[ 0   0   0   0   0   0   0   0   0   0   1   1   1   ] <br />
			[ 0   0   0   0   0   0   0   0   0   1   1   3   3   ] <br />
			[ 0   0   0   0   0   0   0   0   1   1   3   3   3   ] <br />
			[ 0   0   0   0   0   0   0   1   1   1   3   3   3   ] <br />
			[ 0   0   0   0   0   0   1   1   3   3   3   3   3   ] <br />
			[ 0   0   0   0   0   1   1   1   3   3   3   3   3   ] <br />
			[ 0   0   0   0   1   2   2   2   3   3   3   3   3   ] <br />
			[ 0   0   0   1   1   2   4   4   4   4   4   4   4   ] <br />
			[ 0   0   1   1   1   2   4   4   4   4   4   4   4   ] <br />
			[ 0   1   2   2   2   2   4   4   4   4   4   4   4   ] <br />
			[ 1   1   2   4   4   4   4   4   4   4   4   4 <B>4</B> ] <br />
			ammaccabanane -&gt; 4<br />
		</TD><br />
	</TR><br />
</TABLE></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/massima-sottostringa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ricerca del minimo numero di caratteri da aggiungere a una stringa per renderla palindroma</title>
		<link>http://www.thedarshan.com/informatica/minima-palindroma/</link>
		<comments>http://www.thedarshan.com/informatica/minima-palindroma/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 16:51:31 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[algoritmica]]></category>
		<category><![CDATA[iterativo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione dinamica]]></category>
		<category><![CDATA[semplice]]></category>
		<category><![CDATA[unipa]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=891</guid>
		<description><![CDATA[Ricerca del minimo numero di caratteri da aggiungere a una stringa per renderla palindroma ( Compito del 28 Settembre 2011) Il testo recita: Una stringa e palindroma se non cambia leggendola da destra a sinistra e viceversa. Ad esempio anna e osso sono due palindromi. Risolvere il seguente problema: data una stringa S = {a &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/minima-palindroma/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<h1>Ricerca del minimo numero di caratteri da aggiungere a una stringa per renderla palindroma ( Compito del 28 Settembre 2011)</h1>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } --><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">Il testo recita:<br />
</span></span></p>
<blockquote><p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } -->Una stringa e palindroma se non cambia leggendola da destra a sinistra e viceversa. Ad esempio anna e osso sono due palindromi.</p>
<p>Risolvere il seguente problema: data una stringa S = {a 1 , a2 , . . . , an } di n caratteri, calcolare il minimo numero di caratteri che occorre inserire per renderla un palindromo.</p>
<p><strong>Suggerimento per la risoluzione:</strong></p>
<p>Sia P [i, j] il numero di caratteri necessari per trasformare la stringa S[i, j] in una stringa palindroma. Il caso base consiste in una stringa di 1 (o meno) caratteri, cioè il caso in cui i = j.</p>
<p>In tal caso ovviamente non serve nessun carattere per rendere la stringa palindroma perch lo gi. Altrimenti se i caratteri S[i] ed S[j] sono uguali allora posso semplicemente risolvere il sottoproblema P [i + 1; j − 1]. Viceversa dovrò inserire almeno un carattere per rendere la stringa palindroma e calcolare il minimo tra i sottoproblemi P [i + 1; j] e P [i; j + 1], risolti ricorsivamente. La definizione ricorsiva di una soluzione ottima potrebbe essere così definita</p>
<p style="text-align: center;"><a href="http://www.thedarshan.com/wp-content/uploads/2012/02/Settembre2011_htm_m24a9b38b.png"><img class="aligncenter size-full wp-image-900" title="Settembre2011_htm_m24a9b38b" src="http://www.thedarshan.com/wp-content/uploads/2012/02/Settembre2011_htm_m24a9b38b.png" alt="" width="442" height="68" /></a></p>
<p>La risoluzione del problema mediante l’utilizzo della programmazione dinamica prevede quindi la costruzione di una tabella di dimensione n × n.</p></blockquote>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } 		H2 { margin-bottom: 0.21cm } 		H2.western { font-family: "Arial", sans-serif; font-size: 14pt; font-style: italic } 		H2.cjk { font-size: 14pt; font-style: italic } 		H2.ctl { font-size: 14pt; font-style: italic } --></p>
<h3>Implementazione ricorsiva</h3>
<pre class="brush: cpp; title: ; notranslate">
int p(char s[], int da, int a){
  if(da&gt;=a)return 0;
  if (s[a]==s[da])return p(s, da+1, a-1);
  int r=p(s,da+1,a);
  int l=p(s,da,a-1);
  int x=r-l;
  if(x&gt;0)
    return l+1;
  else
    return r+1;
}

int palindromizza(char stringa[]){
  return p(stringa, 0, strlen(stringa)-1);
}
</pre>
<p><!-- 		@page { margin: 2cm } 		P { margin-bottom: 0.21cm } --><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">La fuzione viene implementata applicando semplicemente la formula di ricorsione</span></span></p>
<h3>Implementazione Dinamica</h3>
<pre class="brush: cpp; title: ; notranslate">
int p_d(char s[], int da, int a, int r, int c, int v[ r ][ c ] )
{
    if (da &gt;= a)
    {
        return 0;
    }
    if (s[a] == s[da])
    {
        return v[da + 1][a - 1];
    }
    int destra = v[da + 1][a];
    int sinistra = v[da][a - 1];
    int delta = destra - sinistra;
    if (delta &gt; 0)
    {
        return sinistra + 1;
    }
    else
    {
        return destra + 1;
    }
}

int p_iterativa(char stringa[])
{
    int len=strlen(stringa);
    int **v=malloc(sizeof(int)*len*len);
    int i,j;
    for(i=0;i&lt;len;i++){
        for(j=0;j&lt;(len-i);j++){
            int pal=p_d(stringa,j,i+j,len,len,v);
            v[j*len+(i+j)]=pal;
        }
    }
    len=v[len-1];
    free(v);
    return len;
}
</pre>
<p><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">L&#8217;implementazione dinamica viene creata modificando la funzione ricorsiva in modo che i valori già calcolati vengano letti da una matrice invece che ricalcolati. I valori per cui c&gt;r sono necessariamente 0 (quelli sopra la diagonale principale) e non vanno calcolati. </span></span></p>
<p><span style="font-family: Times New Roman,serif;"><span style="font-size: small;"><em>L&#8217;unico modo di percorrere la matrice senza creare dipendenze da valori non ancora calcolati è per diagonali.</em></span></span></p>
<p><span style="font-family: Times New Roman,serif;"><span style="font-size: small;">Esempi di matrici dei valori parziali</span></span></p>
<table border="0" cellspacing="0" cellpadding="4" width="100%">
<colgroup>
<col width="85*"></col>
<col width="85*"></col>
<col width="85*"></col>
</colgroup>
<tbody>
<tr valign="TOP">
<td width="33%">[ 0   0   0   0   0   ]<br />
[ 0   0   0   0   1   ]<br />
[ 0   0   0   1   2   ]<br />
[ 0   0   1   0   1   ]<br />
[ 0   1   2   1   <strong>0</strong> ]ABCBA -&gt; 0</td>
<td width="33%">[ 0 0 0 0 0 ]<br />
[ 0 0 0 0 1 ]<br />
[ 0 0 0 0 1 ]<br />
[ 0 0 1 1 0 ]<br />
[ 0 1 0 1 <strong>1</strong> ]pappa -&gt; 1</td>
<td width="33%">[ 0 0 0 0 0 ]<br />
[ 0 0 0 0 1 ]<br />
[ 0 0 0 1 2 ]<br />
[ 0 0 1 2 3 ]<br />
[ 0 1 2 3 <strong>4</strong> ]abcde -&gt; 4</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/minima-palindroma/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Come creare una sottorete sottoposta a sniffing utilizzando un router supplementare</title>
		<link>http://www.thedarshan.com/elettronicadevices/sottoreteconsniffing/</link>
		<comments>http://www.thedarshan.com/elettronicadevices/sottoreteconsniffing/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 22:01:04 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Elettronica/Devices]]></category>
		<category><![CDATA[Informatica]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[honeypot]]></category>
		<category><![CDATA[iptables]]></category>
		<category><![CDATA[networking]]></category>
		<category><![CDATA[rottorete]]></category>
		<category><![CDATA[router]]></category>
		<category><![CDATA[routing]]></category>
		<category><![CDATA[sniffing]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=857</guid>
		<description><![CDATA[In questo post descriverò la procedura che ho utilizzato per creare una sottorete all&#8217;interno della mia rete domestica da utilizzare per eseguire analisi delle cominicazioni di rete ( per motivi di sviluppo o di sicurezza) o per creare Honeypot. L&#8217;idea era quella di creare una seconda rete collegata alla rete domestica e quindi a internet &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/elettronicadevices/sottoreteconsniffing/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">In questo post descriverò la procedura che ho utilizzato per creare una sottorete all&#8217;interno della mia rete domestica da utilizzare per eseguire analisi delle cominicazioni di rete ( per motivi di sviluppo o di sicurezza) o per creare <em>Honeypot</em>. L&#8217;idea era quella di creare una seconda rete collegata alla rete domestica e quindi a internet attraverso un host che fa da <em>proxy</em> ( nel senso etimologico del termine) che chiameremo <strong>Routing server</strong> e logga tutte le conversazioni verso l&#8217;esterno per poterle analizzare in seguito.</p>
<h3 style="text-align: left;">I requisiti sono quindi:</h3>
<ul>
<li>La sottorete creata deve aver accesso diretto e trasparente ad internet</li>
<li>Tutto il traffico che attraversa il gateway della sottorete deve essere loggato ( quindi sia quello che esce che quello che entra)</li>
<li>Il traffico della sottorrete esistente ( incluso quello generato dal server di routing su eth1 che non è di forwarding) non deve essere loggato</li>
<li>Il traffico strettamente interno alla sottorete è irrilevante</li>
<li>L&#8217;interazione della sottorete con la rete interna preesistente deve essere minimo</li>
</ul>
<h3>La topologia di rete utilizzata è</h3>
<p>Descrivendo la topologia dal punto di vista del <strong>Routing Server</strong> si ha la configurazione seguente:</p>
<ul>
<li>All&#8217;interfaccia <strong>Eth1</strong> è collegato il router che ha l&#8217;accesso ad internet, ad esso è collegata anche la sottorete preesistente</li>
<li>L&#8217;indirizzo del Routing server in Eth0 è <strong>192.168.1.64</strong></li>
<li>L&#8217;indirizzo del Routing server in Eth0 è <strong>192.168.0.5</strong>, dovrà fare da gateway per il router interno</li>
<li>L&#8217;indirizzo (interno) del router connesso ad internet è <strong>192.168.1.254</strong></li>
<li>L&#8217;indirizzo del router interno è <strong>192.168.0.1<br />
</strong></li>
<li>All&#8217;interfaccia <strong>Eth0</strong> è collegato un secondo router ( in particolare un router wireless visto che la funzione principale del progetto è studiare applicazioni Android)</li>
<li>Il router connesso ad internet ha una sottorrete definita dalla netmask <strong>192.168.1.0/24</strong></li>
<li>il router interno una sottorete definita dalla netmask <strong>192.168.0.0/24</strong></li>
</ul>
<p><strong>Routing Server</strong> collega le due sottoreti attraverso funzioni di forwarding implementate attraverso iptables, è quindi un host <strong>Linux</strong></p>
<p style="text-align: left;">
<p style="text-align: center;"><a href="http://www.thedarshan.com/wp-content/uploads/2012/01/Schema_sniff.png"><img class="aligncenter size-full wp-image-860" title="Schema_sniff" src="http://www.thedarshan.com/wp-content/uploads/2012/01/Schema_sniff.png" alt="" width="449" height="328" /></a></p>
<h2 style="text-align: left;">Configurazione del Routing server</h2>
<p>Come dicevo il routing server è un host linux con due schede di rete che collega le due sottoreti forwardando i pacchetti con iptables. Per rendere possibile questo dobbiamo innanzitutto terminare il servizio network manager ( <em>/etc/init.d/network-manager stop</em> )</p>
<p>La configurazione viene eseguita attraverso uno script e viene quindi annullata al riavvio. lo script è il seguente:</p>
<pre class="brush: bash; title: ; notranslate">
#parte1
pkill dhclient
ifconfig eth0 192.168.0.5
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth0 gw 192.168.1.64
route del default
route add default gw 192.168.1.254

#parte2
echo 1 &gt; /proc/sys/net/ipv4/ip_forward
iptables -F
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
iptables -A POSTROUTING -t nat -o eth1 -j MASQUERADE
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -o eth1 -i eth0 -j ACCEPT

#parte3
iptables -A FORWARD -p tcp -s 192.168.0.5/24 --sport 135 -j DROP #microsoft epmap
iptables -A FORWARD -p udp -s 192.168.0.5/24 --sport 137 -j DROP #netbios ns
iptables -A FORWARD -p tcp -s 192.168.0.5/24 --sport 138 -j DROP #netbios dgm
iptables -A FORWARD -p udp -s 192.168.0.5/24 --sport 1900 -j DROP #SSDP
iptables -A FORWARD -p tcp -s 192.168.0.5/24 --sport 445 -j DROP #microsoft-ds
</pre>
<p>vediamo di descrivere lo script:</p>
<h3>la <strong>#parte1 </strong></h3>
<p>termina i servizi di dhcp ancora in vita e poi setta in maniera statica l&#8217;indirizzo di <strong>Eth0</strong> e setta il gateway di <strong>Eth0</strong> a 192.168.1.64 e il gateway di default a 192.168.1.254 (il router connesso)</p>
<h3>la <strong>#parte2</strong></h3>
<p>attiva e configura il forwarding tra le due interfacce<strong>, </strong>la prima riga lo attiva nel caso fosse disattivato<strong> </strong></p>
<h3>la <strong>#parte3</strong></h3>
<p>filtra i pacchetti provenienti da protocolli tipici di windows e provenienti dalla rete preesistente<strong> </strong>. questi pacchetti gonfierebbero inutilmente la dimensione dei file di log</p>
<h2>Configurazione del router interno</h2>
<p>Il router interno dovrà utilizzare 192.168.0.5 come gateway ( indirizzo di Router Server su Eth0) ma utilizzare un dns esterno ( nel mio caso opendns)</p>
<p>L&#8217;indirizzamento dhcp deve essere configurato facendo in modo che siano dinamici solo gli indirizzi superiori a 192.168.0.5</p>
<h2>Sniffing!</h2>
<p>Una volta configurato il tutto lo sniffing è molto semplice, basta avviare uno sniffer qualunque ( tcpdump, wireshark) e metterlo in ascolto su Eth0</p>
<p>In questo modo possiamo anche continuare a navigare senza che il nostro traffico compaia nei log</p>
<p><a href="http://www.thedarshan.com/wp-content/uploads/2012/01/Wireshark.jpg"><img class="aligncenter size-full wp-image-878" title="Wireshark" src="http://www.thedarshan.com/wp-content/uploads/2012/01/Wireshark.jpg" alt="" width="500" height="375" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/elettronicadevices/sottoreteconsniffing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>le Condition, implementazione delle code di attesa. il problema del barbiere addormentato (C++0x)</title>
		<link>http://www.thedarshan.com/informatica/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/</link>
		<comments>http://www.thedarshan.com/informatica/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 15:14:53 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[attesa]]></category>
		<category><![CDATA[barbiere addormentato]]></category>
		<category><![CDATA[broadcast]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++0X]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[condition]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[Dijkstra]]></category>
		<category><![CDATA[eccezioni]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[notify]]></category>
		<category><![CDATA[processo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione concorrente]]></category>
		<category><![CDATA[programmazione parallela]]></category>
		<category><![CDATA[signal]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[wait]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=808</guid>
		<description><![CDATA[Le Condition Le Condition sono un meccanismo di sincronizzazione che permette ai thread di sospendersi in attesa che avvenga un evento e di essere risvegliati quando l’evento accade, permettono quindi di creare delle code di attesa. Nelle STL le condition sono oggetti della classe std::condition_variable , i metodi fondamentali per usarle sono tre: wait() permette &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<h2>Le Condition</h2>
<p>Le <strong>Condition</strong> sono un meccanismo di sincronizzazione che permette ai thread di sospendersi in attesa che avvenga un evento e di essere risvegliati quando l’evento accade, permettono quindi di creare delle code di attesa.</p>
<p>Nelle STL le condition sono oggetti della classe <strong><em>std::condition_variable </em></strong>, i metodi fondamentali per usarle sono tre:</p>
<ul>
<li><strong>wait()</strong> permette di accodarsi alla condition</li>
<li><strong>notify_one() notify_all() </strong>permettono      di risvegliare uno o tutti i thread in attesa sulla coda (nell’implementazione      tradizionale dei pthread si chiamavano signal e broadcast)<strong> </strong></li>
</ul>
<p>A una Condition è sempre associato un mutex per evitare <em>race condition </em>che potrebbe creare un thread che si sta preparando a una <em>wait</em> mentre un altro thread esegue una <em>signal, </em>la signal potrebbe infatti avvenire contemporaneamente alla wait e venire quindi persa creando un deadlock, può essere usato un mutex qualunque o si può creare un mutex proprio della condition</p>
<p>Vediamone il funzionamento con un semplice codice: 10 thread si mettono in coda su una condition e un altro thread li sveglia uno per volta</p>
<pre class="brush: cpp; title: ; notranslate">#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;

using namespace std;

class Worker
{
public :

    int numero;
    std::condition_variable *coda;
    mutex *m;
    Worker(int n, std::condition_variable *cond, mutex *mtx)
    {
        coda=cond;
        numero=n;
        m=mtx;
    }
    void operator()()
    {
        cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; allocato, mi metto in coda&quot; &lt;&lt; endl;
        std::unique_lock&lt;std::mutex&gt; lk(*m);
        coda-&gt;wait(lk);
        cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; risvegliato dalla coda&quot; &lt;&lt; endl;
    }
};

int main()
{
    std::condition_variable *coda= new condition_variable();
    mutex *m= new mutex();
    int a;

    std::thread* threads[10];

    for(a=0;a&lt;10;a++){//creo
        threads[a]= new std::thread(Worker(a+1,coda,m));
        usleep( 100000 );
    }
    for(a=0;a&lt;10;a++){//sveglio
        usleep( 1000 * ( rand() % 900));
        coda-&gt;notify_one();
    }
    for(a=0;a&lt;10;a++)//aspetto termine
    {
        threads[a]-&gt;join();
        delete(threads[a]);
    }
};
</pre>
<h3>Ma le cose non sono così semplici&#8230;</h3>
<ul>
<li>Malgrado di solito non succeda le specifiche dei pthread non garantiscono che l&#8217;ordine in cui i thread si sveglino sia uguale a quello in cui si addormentano, quindi in caso di applicazioni dove l&#8217;ordine degli accessi è importante questo va verificato esplicitamente.</li>
<li>Un altra cosa che potrebbe succedere ( e questa è più grave ) è che più di un thread venga liberato dalla coda, quindi i thread appena svegliati devono di nuovo verificare che la condizione che li ha fatti accodare sia stata soddisfatta ed eventualmente rimettersi in coda.</li>
</ul>
<h3>Il problema del barbiere addormentato</h3>
<div class="wp-caption alignleft" style="width: 250px"><a href="http://www.flickr.com/photos/15243848@N00/3649134177/"><img title="Un barbiere di Lisbona..." src="http://farm4.staticflickr.com/3351/3649134177_88431d9d8a_m.jpg" alt="Un barbiere di Lisbona..." width="240" height="240" /></a><p class="wp-caption-text">Un barbiere di Lisbona...</p></div>
<p>Vediamo un applicazione delle condition a un problema più complesso, il problema del barbiere addormentato di Dijkstra. il problema è definito in questo modo:</p>
<blockquote><p>Un negozio di barbiere è costituito da una sala con una sola poltrona sulla quale si accomoda il cliente che viene servito e da una sala d&#8217;attesa con n sedie. Se non ci sono clienti da servire il bar­biere va a dormire. Se arriva un cliente e tutte le sedie della sala d&#8217;attesa sono occupate, il clien­te va via, mentre, se c&#8217;è una sedia libera e il barbiere è occupato, il cliente attenderà, seduto, il proprio turno. Se il barbiere sta dormendo (cioè è libero, senza clienti in attesa), il cliente lo sve­glia e viene servito subito.</p></blockquote>
<p>La soluzione è più prolissa di quello che potrebbe sembrare a prima vista, tralaltro nell&#8217;implementarlo ho istintivamente usato un monitor anche se non ho accennato a questo tipo di costrutti, ne do soltanto una breve definizione OOP</p>
<p style="text-align: center;"><em><strong>Un monitor è un oggetto che incapsula la risorsa ed espone i metodi per accedervi in maniera sicura</strong></em></p>
<p style="text-align: left;">In questo caso, come si vede nel sorgente sottostante, il contatore delle sedie occupate è nascosto dentro la classe Stanza che mette a disposizione i metodi per occupare e liberare una sedia mantenendoli sincronizzati attraverso un semaforo proprio della classe.</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;
#include &lt;mutex&gt;
#include &lt;condition_variable&gt;

using namespace std;

int dormi(float base, float variabile)
{
    int k=1000*1000;
    int base_i=(int)base*k;
    int variabile_i=0;
    if(variabile&gt;0)variabile_i=rand() % (int)(variabile*k);
    usleep(base_i+variabile_i);
    return base_i+variabile_i;
};

class Stanza
{
private:
    int occupate;
    std::mutex monitor_m;

public:

    std::condition_variable attesa;

    std::mutex attesa_m;
    std::condition_variable poltrona;
    std::condition_variable letto;
    std::mutex barbiere;
    int sedie;

    int prenota()
    {
        std::unique_lock&lt;std::mutex&gt; lk(monitor_m);
        if(occupate&gt;=sedie)return -1;
        occupate++;
        cout &lt;&lt; occupate &lt;&lt; &quot; sedie occupate&quot;&lt;&lt;endl;

        return occupate;
    }

    int guarda()
    {
        std::unique_lock&lt;std::mutex&gt; lk(monitor_m);
        return occupate;
    }

    int libera()
    {
        std::unique_lock&lt;std::mutex&gt; lk(monitor_m);
        occupate--;
        cout &lt;&lt; occupate &lt;&lt; &quot; sedie occupate&quot;&lt;&lt;endl;
        return occupate;
    }

    Stanza(int n_sedie)
    {
        this-&gt;sedie=n_sedie;
        occupate=0;
    }
};

class Barbiere
{
public :

    int numero;
    int azioni;
    Stanza *stanza;
    std::unique_lock&lt;std::mutex&gt; *barbiere;
    Barbiere(Stanza *st)
    {
        azioni=0;
        this-&gt;stanza=st;
        barbiere= new std::unique_lock&lt;std::mutex&gt;(stanza-&gt;barbiere,std::defer_lock_t());

    }
    void operator()()
    {
        while(true)
        {
            cout &lt;&lt; &quot;Barbiere controlla se ci sono clienti in attesa&quot;&lt;&lt;endl;

            if(stanza-&gt;guarda()==0)
            {
                cout &lt;&lt; &quot;Barbiere si addormenta&quot;&lt;&lt;endl;
                std::unique_lock&lt;std::mutex&gt; lk(stanza-&gt;barbiere);
                stanza-&gt;letto.wait(lk);
            }

            cout &lt;&lt; ++azioni &lt;&lt;&quot; Barbiere serve un cliente&quot;&lt;&lt;endl;
            stanza-&gt;attesa.notify_one();
            dormi( 2 , 2 );
            stanza-&gt;poltrona.notify_one();
        }
    }
};

class Cliente
{
public :

    int numero;
    Stanza *stanza;
    std::unique_lock&lt;std::mutex&gt; *barbiere;
    Cliente(Stanza *st, int n)
    {
        stanza=st;
        numero=n;
        barbiere= new std::unique_lock&lt;std::mutex&gt;(stanza-&gt;barbiere,std::defer_lock_t());

    }
    void work()
    {
        cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; allocato, entra dal barbiere&quot; &lt;&lt; endl;
        int s=stanza-&gt;prenota();

        if(s&lt;0)
        {
            cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; tutte le sedie sono occupate, esce&quot; &lt;&lt; endl;
            return;
        }
        else
        {
            if(s&gt;0)
            {
                cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; si siede e aspetta&quot; &lt;&lt; endl;
                if (s==1)
                {
                    cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; sveglia il barbiere&quot; &lt;&lt; endl;
                    dormi(1,0);
                    stanza-&gt;letto.notify_one();
                }
                std::unique_lock&lt;std::mutex&gt; lk(stanza-&gt;attesa_m);
                stanza-&gt;attesa.wait(lk);
                cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; si alza&quot; &lt;&lt; endl;
                stanza-&gt;libera();
            }

            barbiere-&gt;lock();
            cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; si siete e si fa rasare&quot; &lt;&lt; endl;
            stanza-&gt;poltrona.wait(*barbiere);
            barbiere-&gt;unlock();
            cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; esce&quot; &lt;&lt; endl;

        }

    }
    void operator()()
    {
        for(int a=0; a&lt;2; a++)
        {
            work();
            cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; va in giro a bighellonare&quot; &lt;&lt; endl;
            dormi(30,30);
        }
        cout &lt;&lt; &quot;Thread&quot;&lt;&lt; numero &lt;&lt; &quot; muore&quot; &lt;&lt; endl;
    }
};

int main(int argc, char** argv)
{
    Stanza stanza(5);
    int a;

    std::thread* threads[15];

    std::thread* barbiere=new std::thread(Barbiere(&amp;stanza));
    for(a=0; a&lt;15; a++)   //creo
    {
        dormi(0,a);
        threads[a]= new std::thread(Cliente(&amp;stanza,a+1));
    }
    for(a=0; a&lt;15; a++)   //aspetto termine
    {
        threads[a]-&gt;join();
        delete(threads[a]);
    }
};
</pre>
<p>Il problema è risolto nel modo seguente:</p>
<h3>Il barbiere:</h3>
<ol>
<li>Controlla se ci sono clienti in attesa (attraverso i metodi del Monitor)</li>
<li>se non ce ne sono si addormenta ( svegliandosi al punto 3)</li>
<li>se ce ne sono li rade e torna al punto 1</li>
</ol>
<p>la rasatura consiste in:</p>
<ul>
<li>liberare un Cliente dalla coda della sala di attesa (attesa.notify_one) , il cliente liberato occupa la coda della poltrona</li>
<li>radere il Cliente, liberarlo dalla coda della poltrona (poltrona.notify_one())</li>
</ul>
<h3>Il Cliente</h3>
<ol>
<li>Entra nella sala, cerca di sedersi
<ol>
<li>Se può sedersi:
<ol>
<li>Se è l&#8217;unica persona seduta sveglia il barbiere (letto.notify_one())</li>
<li>va al punto 2</li>
</ol>
</li>
<li>Se non può sedersi esce dalla sala e va al punto 5</li>
</ol>
</li>
<li>Si mette in attesa nella coda della sala (attesa.wait(lk))</li>
<li>una volta svegliato occupa il barbiere (barbiere-&gt;lock()) e si mette in attesa sulla sedia della poltrona (poltrona.wait(*barbiere)).<br />
il mutex sul barbiere evita il problema di una possibile signal non voluta ( vedi sopra il paragrafo &#8220;ma le cose non sono così semplici&#8221;)</li>
<li>una volta svegliato libera il barbiere ed esce dalla sala</li>
<li>va in giro a bighellonare e poi torna al punto 1</li>
</ol>
<p>In questa implementazione sono possibili delle signal superflue su un barbiere già sveglio, ma sono irrilevanti</p>
<p>Con questo articolo ho concluso la serie sulla programmazione concorrente in Cpp0X<span id="more-808"></span></p>
<p>Questo post fa parte di una serie, gli altri post riguardanti il Cpp0X sono:</p>
<ul>
<li><a title="Permalink to Il C++ non è ancora morto" href="../2011/02/il-c-non-e-ancora-morto/">Il C++ non è ancora morto</a></li>
<li><a title="Permalink to il C++ e le lambda ( C++0X)" href="../2011/03/il-cp-e-le-lambda-c0x/">il C++ e le lambda (      C++0X)</a></li>
<li><a title="Permalink to Il C++ e il Multithreading (C++0X)" href="../2011/10/il-c-e-il-multithreading-c0x/">Il C++ e il      Multithreading (C++0X)</a></li>
<li><a title="Permalink to Sincronizzazione dei Thread e gestione delle risorse con i Mutex ( C++0X)" href="../2011/10/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/">Sincronizzazione      dei Thread e gestione delle risorse con i Mutex ( C++0X)</a></li>
<li><a title="Permalink to Uso avanzato dei Mutex, i 5 Filosofi (C++0x)" href="../2011/11/uso-avanzato-dei-mutex-i-5-filosofi-c0x/">Uso      avanzato dei Mutex, i 5 Filosofi (C++0x)</a></li>
<li><a title="Permalink to le Condition, implementazione delle code di attesa. il problema del barbiere addormentato (C++0x)" href="../2011/11/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/">Le      Condition, implementazione delle code di attesa. il problema del barbiere      addormentato (C++0x)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uso avanzato dei Mutex, i 5 Filosofi (C++0x)</title>
		<link>http://www.thedarshan.com/informatica/uso-avanzato-dei-mutex-i-5-filosofi-c0x/</link>
		<comments>http://www.thedarshan.com/informatica/uso-avanzato-dei-mutex-i-5-filosofi-c0x/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 12:59:22 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++0X]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[Dijkstra]]></category>
		<category><![CDATA[eccezioni]]></category>
		<category><![CDATA[filosofi]]></category>
		<category><![CDATA[guard]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[processo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione concorrente]]></category>
		<category><![CDATA[programmazione parallela]]></category>
		<category><![CDATA[thread]]></category>
		<category><![CDATA[unique_lock]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=763</guid>
		<description><![CDATA[Nell&#8217;articolo precedente ho parlato del mutex e del suo uso semplice con la lock_guard. in questo tratterò gli altri tipi di guard e l&#8217;uso avanzato dei mutex unique_lock Con unique_lock un mutex può fare molto di più di quello che permette la lock_guard : Si può cercare di prenotarlo in maniera non bloccante ( se &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/uso-avanzato-dei-mutex-i-5-filosofi-c0x/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Nell&#8217;articolo precedente ho parlato del mutex e del suo uso semplice con la <em>lock_guard. </em>in questo tratterò gli altri tipi di <strong>guard</strong> e l&#8217;uso avanzato dei mutex</p>
<h3>unique_lock</h3>
<p>Con <em>unique_lock</em> un mutex può fare molto di più di quello che permette la <em>lock_guard</em> :</p>
<ul>
<li>Si può cercare di prenotarlo in maniera non bloccante ( se è libero lo si occupa, se non è libero non si attende)</li>
<li>Si può cercare di prenotarlo fornendo un timeout massimo di attesa ( se si tratta di un timed mutex ovviamente)</li>
<li>Si può accedere direttamente alle funzioni del mutex</li>
</ul>
<p>e un sacco di altre cose per le quali vi rimando a una <a href="http://www.stdthread.co.uk/">reference</a> ( lo so, non è ufficiale&#8230; ma non ho trovato di meglio )</p>
<h3>Timed mutex e la prenotazione con timeout massimo</h3>
<p>Disponendo di un timed mutex potremmo per esempio eseguire questo:</p>
<pre class="brush: cpp; title: ; notranslate">
std::timed_mutex m;
std::unique_lock&lt;std::timed_mutex&gt;
 lk(m,std::chrono::milliseconds(5));
if(lk)work()
}
</pre>
<p>Questa funzione prova ad accedere al mutex aspettando massimo 5 millisecondi, il valore della lock si usa per determinare se l&#8217;accesso è avvenuto o no</p>
<h3>Accesso alle funzioni interne del mutex</h3>
<p>Attraverso la unique_lock possiamo accedere alle funzioni del mutex, ma questa volta le eccezioni sono gestite.</p>
<pre class="brush: cpp; title: ; notranslate">
std::mutex m;
void zona_critica()
{
 std::unique_lock&lt;std::mutex&gt; lk(m);
 // in questo momento il mutex è occupato
 lk.unlock();
 // in questo momento il mutex è libero
 lk.lock();
 //in questo momento il mutex è di nuovo occupato
}
</pre>
<p>Possiamo anche evitare che il mutex venga occupato all&#8217;allocazione della unique_lock utilizzando un costruttore diverso:</p>
<pre class="brush: cpp; title: ; notranslate">
std::mutex m;
void zona_critica()
{
 std::unique_lock&lt;std::mutex&gt; lk(m,std::defer_lock_t());
 // in questo momento il mutex è libero
 lk.lock();
 // in questo momento il mutex è occupato
 lk.unlock();
 //in questo momento il mutex è di nuovo libero
}
</pre>
<h3>Prenotazione multipla</h3>
<p>Un problema molto comune nella programmazione concorrente è la necessita da parte di un processo di accedere in maniera esclusiva a più risorse, è un problema che se gestito male può causare facilmente deadlock o starvation in quanto se un processo che ha acquisito parte delle risorse necessarie attende altre risorse per continuare e queste risorse sono bloccate da altri processi anche loro in attesa tutti i processi restano bloccati in attesa l&#8217;uno dell&#8217;altro, in questo caso le stl ci vengono in aiuto dandoci un costrutto che permette di bloccare n mutex restando in attesa ma non bloccandoli</p>
<pre class="brush: cpp; title: ; notranslate">
void prenota(std::mutex *a ,std::mutex *a)
 {
 std::unique_lock&lt;std::mutex&gt; lock_a(*a, std::defer_lock);
 std::unique_lock&lt;std::mutex&gt; lock_b(*b, std::defer_lock);
 std::lock(lock_a,lock_b);

 // fai qualcosa di critico
 }
</pre>
<h3>Il problema dei 5 filosofi</h3>
<div id="attachment_799" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.thedarshan.com/wp-content/uploads/2011/11/Filosofi_mono.png"><img class="size-medium wp-image-799" title="Filosofi_mono" src="http://www.thedarshan.com/wp-content/uploads/2011/11/Filosofi_mono-300x256.png" alt="" width="300" height="256" /></a><p class="wp-caption-text">Illustrazione originale dal testo di Dijkstra</p></div>
<p>Un problema molto interessante che illustra la potenzialità di questo costrutto è il problema dei 5 filosofi a cena, esso è stato formulato da Dijkstra intorno al 1965, per mettere alla prova le primitive di sincronizzazione dell&#8217;epoca ( i semafori fondamentalmente) il problema è questo (cito dal testo di Silberschatz) :</p>
<blockquote><p>Si considerino cinque filosofi che passano la vita pensando e mangiando. I filosofi con­dividono un tavolo rotondo circondato da cinque sedie, una per ciascun filosofo. Al cen­tro del tavolo si trova una zuppiera colma di riso, e la tavola è apparecchiata con cinque bacchette. Quando un filosofo pensa, non interagisce con i colleghi; quan­do gli viene fame, tenta di prendere le bacchette più vicine: quelle che si trovano tra lui e i commensali alla sua destra e alla sua sinistra. Un filosofo può prendere una bacchetta alla volta e non può prendere una bacchetta che si trova già nelle mani di un suo vicino. Quando un filosofo affamato tiene in mano due bacchette contemporaneamente, man­gia senza lasciare le bacchette. Terminato il pasto, le posa e riprende a pensare.</p></blockquote>
<p>&#8220;Il problema dei cinque filosofi è considerato un classico problema di sincronizzazione, non certo per la sua importanza pratica, e neanche per antipatia verso i filosofi da parte degli informatici, ma perché rappresenta una vasta classe di problemi di controllo della concorrenza, in particolare i problemi caratterizzati dalla necessità di assegnare varie risorse a diversi processi evitando situazioni di stallo e d&#8217;attesa indefinita.&#8221; la parola <em>starvation </em>deriva proprio da questo problema&#8230; se non si riesce a gestire la cosa i filosofi muoiono di fame ( to starve in inglese)</p>
<p>Una semplice soluzione consiste nel rappresentare ogni bacchetta con un mutex: un filosofo tenta di afferrare ciascuna bacchetta eseguendo un&#8217;operazione lock su quel mutex e la posa eseguendo una unlock.</p>
<p>Partendo da questo modello possiamo cominciare a cercare una soluzione, quella più immediata potrebbe esere:</p>
<p style="text-align: right;"><em>un filosofo prende la bacchetta a destra, poi quella a sinistra e poi mangia</em></p>
<p style="text-align: left;">ma cosa succede se tutti prendono contemporaneamente la forchetta di destra? un deadlock, muoiono di fame aspettando che qualcuno liberi qualcosa ma nessuno libererà mai niente.</p>
<p style="text-align: left;">un&#8217;altra soluzione potrebbe essere:</p>
<p style="text-align: right;"><em>Un filosofo di numero pari prende prima la forchetta di destra e poi quella di sinistra, un filosofo dispari il contrario</em></p>
<p style="text-align: left;">Ma questo è barare xD scartiamola</p>
<p style="text-align: left;">Ci rendiamo conto che un filosofo deve rilasciare la bacchetta se non può prendere la seconda, qualcosa del tipo</p>
<p style="text-align: right;"><em>Un filosofo prende la bacchetta di destra, poi cerca di prendere quella di sinistra (trylock) e se non può le posa entrambe e riprova in seguito</em></p>
<p style="text-align: left;">ma che succede se i filosofi partono insieme? l&#8217;algoritmo va in loop: tutti prendono quella di destra, nessuno può prendere quella a sinistra, tutti posano tutto e si ricomincia, <em>le operazioni necessitano di essere eseguite in maniera atomica:</em></p>
<p style="text-align: right;"><em><strong>Un filosofo cerca di prendere entrambe le bacchette contemporaneamente, se non può aspetta</strong></em></p>
<p style="text-align: left;">Questo comportamento non può essere costruito direttamente usando i singoli mutex, ma possiamo farlo con il nostro <em>std::lock(lock_a,lock_b)</em></p>
<p style="text-align: left;">La soluzione tradizionale necessita della costruzione di un Monitor, ma non me ne occuperò qui, sfruttiamo a pieno le stl e riduciamo il problema a una cosa banale, con buona pace di Dijkstra</p>
<pre class="brush: cpp; title: ; notranslate">
...
class Filosofo {
public :

    int id;
    mutex *destra;
    mutex *sinistra;
    Filosofo(int n, mutex *d, mutex *s) {
        id=n;
        destra=d;
        sinistra=s;
    }

    void pensa() {
        string argomenti[5]= {
            &quot;Alla fame nel mondo&quot;,
            &quot;Al punto G&quot;,
            &quot;All origine dell Universo&quot;,
            &quot;Al senso della vita&quot;,
            &quot;Alla domanda la cui risposta e' 42&quot;
        };
        cout &lt;&lt; id &lt;&lt; &quot;: Sto pensando... &quot; &lt;&lt; argomenti[id] &lt;&lt; endl;
        usleep( 10000 * ( rand() % 90 + 10 ));
    };

    void mangia() {
        printf(&quot;%d: Cerco le bacchette...\n&quot;,id);
        std::unique_lock&lt;std::mutex&gt; lock_a(*destra, std::defer_lock);
        std::unique_lock&lt;std::mutex&gt; lock_b(*sinistra, std::defer_lock);
        std::lock(lock_a,lock_b);
        printf(&quot;%d: Sto mangiando...\n&quot;,id);
        usleep( 30000 * ( rand() % 90 + 10 ));
        printf(&quot;%d: Poso le bacchette, sazio\n&quot;,id);
    };

    void operator()() {
        printf(&quot;%d: Penso quindi sono \n&quot;,id);
        usleep( 30000 * ( rand() % 90 + 10 ));
        for(int a=0; a&lt;5; a++) {
            pensa();
            mangia();
        }
    }
};
...
</pre>
<p>La versione completa del codice si trova <a href="http://www.thedarshan.com/home/files/5Filosofi.cpp">qui</a></p>
<p>per questo articolo è meglio fermarmi, sta diventando troppo lungo, le condition le tratto nel prossimo</p>
<h3>References</h3>
<p>Se siete interessati alla versione originale del problema di Dijkstra ,risolta interamente con i semafori, potete dare un occhiata a <a href="http://books.google.com/books?id=LFpzL3529vkC&amp;lpg=PA198&amp;ots=iKcFs5ptMp&amp;dq=%22Hierarchical%20Ordering%20of%20Sequential%20Processes.%22&amp;lr&amp;pg=PA198#v=onepage&amp;q=%22Hierarchical%20Ordering%20of%20Sequential%20Processes.%22&amp;f=false">questo testo</a> su google docs, se poi avete anche interessi archeologici c&#8217;è la scan della versione originale <a href="http://www.cs.utexas.edu/~EWD/ewd03xx/EWD310.PDF">qui</a> (vi avviso, Dijkstra coda in Agol xD)</p>
<p>Che Dio benedica l&#8217;università del texas e google docs, visto che la versione ufficiale nel sito della Springer costa 35€</p>
<p>Il testo di Silberschatz che citavo è <em>&#8220;Sistemi operativi. Concetti ed esempi&#8221; </em>di Abraham Silberschratz, Peter Baer Galvin, Greg Gagne. potete dargli un occhiata <a href="http://books.google.com/books?id=dEGqJtGPwbgC&amp;printsec=frontcover#v=onepage&amp;q&amp;f=false">qui</a> , è finora il miglior libro tradotto in italiano sui sistemi operativi in cui mi sia imbattuto</p>
<h2>L’ambiente utilizzato</h2>
<p>Man mano che ci inoltriamo nella parte più raffinata della libreria abbiamo bisogno di versioni sempre più recenti, stavolta ci serve la 4.6 di gcc oltre a tutte le lib descritte nell&#8217;<a href="http://www.thedarshan.com/2011/10/il-c-e-il-multithreading-c0x/">articolo iniziale sui thread</a></p>
<p><span id="more-763"></span></p>
<p>Questo post fa parte di una serie, gli altri post riguardanti il Cpp0X sono:</p>
<ul>
<li><a title="Permalink to Il C++ non è ancora morto" href="../2011/02/il-c-non-e-ancora-morto/">Il C++ non è ancora morto</a></li>
<li><a title="Permalink to il C++ e le lambda ( C++0X)" href="../2011/03/il-cp-e-le-lambda-c0x/">il C++ e le lambda (      C++0X)</a></li>
<li><a title="Permalink to Il C++ e il Multithreading (C++0X)" href="../2011/10/il-c-e-il-multithreading-c0x/">Il C++ e il      Multithreading (C++0X)</a></li>
<li><a title="Permalink to Sincronizzazione dei Thread e gestione delle risorse con i Mutex ( C++0X)" href="../2011/10/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/">Sincronizzazione      dei Thread e gestione delle risorse con i Mutex ( C++0X)</a></li>
<li><a title="Permalink to Uso avanzato dei Mutex, i 5 Filosofi (C++0x)" href="../2011/11/uso-avanzato-dei-mutex-i-5-filosofi-c0x/">Uso      avanzato dei Mutex, i 5 Filosofi (C++0x)</a></li>
<li><a title="Permalink to le Condition, implementazione delle code di attesa. il problema del barbiere addormentato (C++0x)" href="../2011/11/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/">Le      Condition, implementazione delle code di attesa. il problema del barbiere      addormentato (C++0x)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/uso-avanzato-dei-mutex-i-5-filosofi-c0x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sincronizzazione dei Thread e gestione delle risorse con i Mutex ( C++0X)</title>
		<link>http://www.thedarshan.com/informatica/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/</link>
		<comments>http://www.thedarshan.com/informatica/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/#comments</comments>
		<pubDate>Thu, 20 Oct 2011 11:32:35 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++0X]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[eccezioni]]></category>
		<category><![CDATA[guard]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[mutex]]></category>
		<category><![CDATA[processo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione concorrente]]></category>
		<category><![CDATA[programmazione parallela]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=745</guid>
		<description><![CDATA[L'accesso concorrente ai dati o alle risorse può provocare incoerenze nei dati o situazioni di deadlock nel caso di risorse che prevedono accesso esclusivo, in questo post cercherò di analizzare gli strumenti che C++0X offre per la sincronizzazione. in particolare i Mutex]]></description>
			<content:encoded><![CDATA[<p>Come accennato nel <a href="http://www.thedarshan.com/2011/10/il-c-e-il-multithreading-c0x/" target="_self">post precedente</a> un applicazione che sfrutta il multithreading è costituita da un insieme di processi sequenziali cooperanti, tutti in esecuzione asincrona che possono condividere dati e risorse.</p>
<p>L&#8217;accesso concorrente ai dati o alle risorse può provocare incoerenze nei dati o situazioni di deadlock nel caso di risorse che prevedono accesso esclusivo, in questo post cercherò di analizzare gli strumenti che C++0X offre per la sincronizzazione.</p>
<p>All&#8217;interno di un processo si possono separare le sezioni in cui lavora su dati interni da quelle in cui si accede a dati o risorse condivise, queste ultime vengono dette <em>sezioni critiche</em> e sono quelle di cui si deve curare la sincronizzazione.</p>
<p>Non tratterò in questo articolo le soluzioni &#8220;storiche&#8221; e full-software per la gestione delle sezioni critiche (algoritmi di Dekker, di Peterson, algoritmo del banchiere e del panettiere di Lamport, semafori in spinlock) ma tratterò l&#8217;uso di funzioni messe a disposizione dalla libreria che ci permettono di assicurare la mutua esclusione tra processi attraverso lo scheduler.</p>
<p>Per prima cosa cerchiamo di definire cosa deve succedere su una sezione critica: una volta individuata e minimizzata una sezione critica dobbiamo fare in modo che</p>
<ol>
<li>sia verificata la <strong>mutua esclusione </strong>ossia che soltanto un processo per volta possa trovarsi nella sezione critica</li>
<li>si eviti <strong>l&#8217;attesa indefinita</strong> da parte di un processo che tenta di accedere a una sezione critica occupata</li>
<li>un processo che si trova fuori dalla sezione critica non deve poter interferire con l&#8217;accesso alla sezione critica dei processi in attesa</li>
</ol>
<p>Chi ha lavorato con i pthread in C si renderà conto che è quasi un wrapper a oggetti quello che il cpp ci offre</p>
<h2>Il Mutex</h2>
<p>Lo strumento fondamentale per la sincronizzazione offerto dalle stl è il Mutex, che è la crasi di <strong>mut</strong>ual <strong>ex</strong>lusion e serve appunto ad evitare che più processi del necessario possano accedere ad una sezione critica.<br />
Esistono 4 tipi di mutex:</p>
<ol>
<li>semplice ( <em>std::mutex</em> )</li>
<li>semplice con timeout ( <em>std::timed_mutex</em> )</li>
<li>ricorsivo ( <em>std::recursive_mutex</em> )</li>
<li>ricorsivo con timeout ( <em>std::recursive_timed_mutex</em> )</li>
</ol>
<ul>
<li>un mutex è <strong>semplice</strong> se il suo stato è binario ( libero/occupato ) è invece <strong>ricorsivo</strong> se permette più accessi prima di essere occupato</li>
<li>un mutex è <strong>timed</strong> se è possibile fare in modo che si liberi da solo dopo un certo tempo</li>
</ul>
<p>fondamentalmente un mutex dispone di almeno 3 funzioni:</p>
<ul>
<li><strong>void lock();</strong><br />
che permette di occuparlo o di attenderlo se è già occupato</li>
<li><strong>void unlock();</strong><br />
che permette di liberarlo</li>
<li><strong>bool try_lock();</strong><br />
che permette occuparlo se è possibile senza però rimanere in attesa</li>
</ul>
<p>vediamo come usarli, per prima cosa costruiamo un programma che necessiti di essere sincronizzato</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;
#include &lt;string&gt;

using namespace std;

void stampa(string testo){
 for(int a=0;a&lt;testo.length();a++){
 cout &lt;&lt; testo[a];
 flush(cout);
 usleep( 100 * ( rand() % 900 + 100 ));
 }
 cout &lt;&lt; endl;
}

class Worker
{
public :

 string testo;
 Worker(string t){
 testo=t;
 }
 void operator()()
 {
 stampa(testo);
 }
};

int main()
{
 thread t1(Worker(&quot;Quanto legno roderebbe un roditore se un roditore potesse rodere il legno?&quot;));
 thread t2(Worker(&quot;How much wood could a woodchuck chuck if a woodchuck could chuck wood?&quot;));
 t1.join();
 t2.join();
};
</pre>
<p>il codice ci farà ottenere qualcosa del tipo:</p>
<blockquote><p>QHowu anmtuoc hl egwonodo  rcooudelrd ebbae  wuoond rocdhiutcokr cehuc ske  uinf a r odiwtooroed chpuoctkes csouled  rchoduecrek i l woloegdno??</p></blockquote>
<p>La sincronizzazione si effettua creando un mutex globale e condividendolo tra i thread che vanno sincronizzati e racchiudendo la sezione critica dentro una lock e una unlock</p>
<pre class="brush: cpp; title: ; notranslate">
...

class Worker
{
public :

 string testo;
 mutex *m;
 Worker(string t, mutex *mtx){
 m=mtx;
 testo=t;
 }
 void operator()()
 {
 m-&gt;lock();
 stampa(testo);
 m-&gt;unlock();
 }
};

int main()
{
 mutex *m= new mutex();
 thread t1(Worker(&quot;Quanto legno roderebbe un roditore se un roditore potesse rodere il legno?&quot;,m));
 thread t2(Worker(&quot;How much wood could a woodchuck chuck if a woodchuck could chuck wood?&quot;,m));
 t1.join();
 t2.join();
};
</pre>
<h3>Mutex e eccezioni</h3>
<p>Malgrado l&#8217;accesso diretto alle funzioni del mutex sia possibile è un modo pericoloso di procedere.<br />
Infatti non gestisce le eccezioni, se un thread genera un errore all&#8217;interno della zona critica il thread viene terminato ma il mutex non viene sbloccato, quindi il modo corretto di gestire una sezione critica sarebbe usare un <em>try{}catch</em> in questo modo:</p>
<pre class="brush: cpp; title: ; notranslate">
 void operator()()
 {
    m-&gt;lock();
    try
    {
        stampa(testo);
        m-&gt;unlock();
    }
    catch(...)
    {
        m-&gt;unlock();
        cout &lt;&lt; &quot;Yikes!&quot; &lt;&lt; endl;
    }
 }
</pre>
<p>Un modo più compatto di usare in maniera sicura i mutex si può ottenere usando gli ogetti <em>lock_guard</em> delle stl, che permettono anche di rilasciare il mutex in maniera automatica quando si esce dal blocco in cui sono definite ( lo sbloccano nel loro distruttore per essere precisi), il codice precedente si può riscrivere in questo modo:</p>
<pre class="brush: cpp; title: ; notranslate">
 void operator()()
 {
    lock_guard&lt;mutex&gt; lock(*m);
    stampa(testo);
 }
</pre>
<h4>Precisiamo una cosa però&#8230;</h4>
<p><strong><em>Il fatto che la guard blocchi il mutex non implica che l&#8217;intero programma non venga terminato&#8230; infatti dopo aver sbloccato il mutex propaga l&#8217;eccezione generata a livello superiore e se non c&#8217;è un catch a livello superiore questo equivale alla terminazione del processo padre</em></strong></p>
<p>Quindi se ci limitiamo a guardare questi snippet l&#8217;esempio con la gestione manuale funziona meglio di quello con la lock ma nel caso generale l&#8217;uso della lock è comodo perché ci permette di scrivere codici per la gestione delle eccezioni che non tengono conto del mutex&#8230;spero di essermi spiegato</p>
<p>E con questo concludo l&#8217;articolo, nel prossimo tratterò gli altri tipi di <strong>guard</strong> e le <strong>condition</strong> usati per la gestione di situazioni più complesse</p>
<p><span id="more-745"></span></p>
<p>Questo post fa parte di una serie, gli altri post riguardanti il Cpp0X sono:</p>
<ul>
<li><a title="Permalink to Il C++ non è ancora morto" href="../2011/02/il-c-non-e-ancora-morto/">Il C++ non è ancora morto</a></li>
<li><a title="Permalink to il C++ e le lambda ( C++0X)" href="../2011/03/il-cp-e-le-lambda-c0x/">il C++ e le lambda (      C++0X)</a></li>
<li><a title="Permalink to Il C++ e il Multithreading (C++0X)" href="../2011/10/il-c-e-il-multithreading-c0x/">Il C++ e il      Multithreading (C++0X)</a></li>
<li><a title="Permalink to Sincronizzazione dei Thread e gestione delle risorse con i Mutex ( C++0X)" href="../2011/10/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/">Sincronizzazione      dei Thread e gestione delle risorse con i Mutex ( C++0X)</a></li>
<li><a title="Permalink to Uso avanzato dei Mutex, i 5 Filosofi (C++0x)" href="../2011/11/uso-avanzato-dei-mutex-i-5-filosofi-c0x/">Uso      avanzato dei Mutex, i 5 Filosofi (C++0x)</a></li>
<li><a title="Permalink to le Condition, implementazione delle code di attesa. il problema del barbiere addormentato (C++0x)" href="../2011/11/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/">Le      Condition, implementazione delle code di attesa. il problema del barbiere      addormentato (C++0x)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Il C++ e il Multithreading (C++0X)</title>
		<link>http://www.thedarshan.com/informatica/il-c-e-il-multithreading-c0x/</link>
		<comments>http://www.thedarshan.com/informatica/il-c-e-il-multithreading-c0x/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 17:05:19 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[C++0X]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[processo]]></category>
		<category><![CDATA[programmazione]]></category>
		<category><![CDATA[programmazione concorrente]]></category>
		<category><![CDATA[programmazione parallela]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=722</guid>
		<description><![CDATA[Un’altra funzionalità molto interessante introdotta nel C++0X oltre sono le lambda descritte nell’articolo precedente è il supporto nativo al multithreading.

Esistevano già librerie che si occupavano di multithreading in cpp ma adesso è integrato nel linguaggio...]]></description>
			<content:encoded><![CDATA[<p>Un&#8217;altra funzionalità molto interessante introdotta nel <em>C++0X </em>oltre le lambda descritte nell&#8217;<a href="http://www.thedarshan.com/2011/03/il-cp-e-le-lambda-c0x/">articolo precedente</a> è il supporto nativo al multithreading.</p>
<p>Esistevano già librerie che si occupavano di multithreading in cpp ma adesso è integrato nel linguaggio e nella sua libreria standard anche se il backend che effettivamente alloca i thread è l&#8217;onnipresente libreria pthread.<br />
Cominciamo allora <img src='http://www.thedarshan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  do per scontato che abbiate un minimo di familiarità con la programmazione concorrente e come al solito i particolari per la compilazione ( che stavolta potrebbe essere più complicata del solito) sono alla fine dell&#8217;articolo</p>
<h3>Allochiamo il nostro primo thread</h3>
<p>Un thread è un qualcosa che viene eseguito in parallelo, e quindi si crea attraverso una funzione che è quello che deve fare, non è necessario creare una classe intorno al thread come si farebbe in java, basta passare al costruttore di thread la funzione che deve eseguire il thread costruito o qualcosa di equivalente</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;

using namespace std;

void cosadafare(){
 cout&lt;&lt;&quot;Sono una procedura!&quot;&lt;&lt;endl;
}

class Dummy
{
public :
 void operator()()
 {
 for(int a=0;a&lt;5;a++){
 cout&lt;&lt;&quot;Sono un oggetto, e quindi più figo di una procedura! &quot;&lt;&lt; a &lt;&lt;endl;
 usleep( 1000 * ( rand() % 900 + 100 ));
 }
 }
};

void uccidimi(){
 for(int a=0;a&lt;50;a++){
 cout&lt;&lt;&quot;Io parlo troppo &quot;&lt;&lt; a &lt;&lt;endl;
 usleep( 1000 * ( rand() % 900 + 100 ));
 }
}

int main()
{
 Dummy w;
 std::thread t1(w);
 std::thread t2(cosadafare);
 std::thread t3(uccidimi);

 t1.join();
 t2.join();
 t3.detach();
};
</pre>
<p>Cpp è un linguaggio marcatamente OOP e infatti non è necessario passargli una procedura, basta qualunque ogetto supporti l&#8217;operatore (), possiamo anche creare una classe che definisce questo operatore e passarne un istanza.</p>
<p>E&#8217; interessante notare che quando si chiama un thread su un oggetto, come nel caso di <em>std::thread t1(w), </em>non gli viene passato il vero oggetto ma una sua copia, ma di questo ne parliamo dopo.</p>
<p>Le <em>join</em> servono ad aspettare che i thread finiscono prima di terminare il programma, infatti i thread sono concettualmente &#8216;figli&#8217; del processo padre ( il fatto che lo siano veramente dipende dall&#8217;implementazione) e se terminasse il processo padre i figli verrebbero terminati di conseguenza facendo generare a linux un allarmante messaggio di warning, per terminare un thread prima che abbia finito il suo lavoro si usa <em>detach</em></p>
<h3>Thread e condivisione dei dati</h3>
<p>Uno dei vantaggi dei thread rispetto ai processi è che condividono lo spazio di memoria tra di loro, tutto quello che è nello spazio di indirizzamento del processo padre può essere passato ai figli.</p>
<p>Quindi risulta molto conveniente piazzare dentro un oggetto la procedura del thread e i dati in cui dovrà lavorare ma c&#8217;è un inconveniente: come dicevamo sopra<br />
<strong><em>quando si chiama un thread su un oggetto, come nel caso di <em>std::thread t1(w), </em>non gli viene passato il vero oggetto ma una sua copia </em></strong>, questo è irrilevante nel caso di oggetti che wrappano solo una  procedura ma può essere una fonte di bug subdoli nel caso essi  contengano dati infatti modificando l&#8217;oggetto non modifichiamo niente  all&#8217;interno del thread perché sono oggetti diversi</p>
<p>se vogliamo evitare questo comportamento dobbiamo forzare un passaggio via reference e non abbiamo modo di farlo col linguaggio, dobbiamo affidarci alla magia nera delle stl,la soluzione è: <em>std::thread t1(std::ref(dw));</em></p>
<p>Vediamo un esempio<em><br />
</em></p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;
#include &lt;string&gt;

using namespace std;

class Dummy
{
public :

 string testo;
 string nome;
 void operator()()
 {
 for(int a=0;a&lt;15;a++){
 cout&lt;&lt;nome &lt;&lt; &quot; dice: &quot; &lt;&lt; testo&lt;&lt; &quot; &quot; &lt;&lt; a &lt;&lt;endl;
 usleep( 1000 * ( rand() % 900 + 100 ));
 }
 }
};

int main()
{
 Dummy w,w2;
 w.testo=&quot;ammaccabanane&quot;;
 w.nome=&quot;thread1&quot;;
 w2=w;
 w2.nome=&quot;thread2&quot;;
 std::thread t1(w);
 std::thread t2(std::ref(w2));
 sleep(2);
 w.testo=&quot;Yikes!&quot;;
 w2.testo=&quot;Yikes!&quot;;
 t1.join();
 t2.join();
};</pre>
<p>Eseguendolo noterete che il comportamento del primo thread resta invariato, mentre possiamo agire sul secondo modificando i suoi dati dall&#8217;esterno.</p>
<h3>E se volessi passare parametri alla procedura e magari non usare un oggetto?</h3>
<p>Malgrado la soluzione di un oggetto di wrapper può tornare utile il passare dei parametri alla procedura chiamante, il che ci permette anche di non usare completamente un oggetto e di passare tutti i dati su cui deve lavorare il thread alla funzione che ne costituisce il main, vediamo come funziona</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;iostream&gt;
#include &lt;thread&gt;
#include &lt;cstdlib&gt;
#include &lt;string&gt;

using namespace std;

void stampa(string cosa, string altracosa){
 for(int a=0;a&lt;10;a++){
 cout&lt;&lt; cosa &lt;&lt; altracosa &lt;&lt; endl;
 sleep(1);
 }
}

int main()
{
 std::thread t1(stampa, &quot;bla bla bla&quot;, &quot; yada yada yada&quot;);
 t1.join();
};
</pre>
<p>semplicemente accodiamo i parametri da passare alla funzione e ci affidiamo alle stl per la determinazione corretta del tipo ( la sintassi per gli argomenti multipli esisteva già, ma è stata migliorata, se siete curiosi leggete <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf" target="_blank">qui</a> )</p>
<p>e per concludere passiamo alle questioni pratiche</p>
<h3>L&#8217;ambiente utilizzato</h3>
<p>Per l&#8217;ambiente utilizzato valgono le considerazioni fatte nel post precedente più qualcos&#8217;altro:<br />
le funzioni lambda del C++0X sono incluse nei compilatori GNU a partire dalla 4.5 mentre la maggior parte dei sistemi linux attualmente in circolazione usa la 4.3, questa volta però non possiamo aggirare il problema installandocci  MinGW da windows, infatti sorgono altri problemi, i phread.<br />
La libreria dei thread appena destritta usa pthread per creare e gestire i thread, e l&#8217;implementazione della libreria per windows non include pthread, quindi questa volta ci serve una vera Linux con un vero gcc ( oppure un implementazione commerciale per windows tipo <a href="http://www.justsoftwaresolutions.co.uk/">questa </a>che però non ho verificato, se qualcuno lo fa può scrivere sui commenti come funziona e se funziona e se ne vale la pena)</p>
<ul>
<li>Anche lavorando con la 4.5 di default il compilatore non accetta la nuova sintassi, bisogna specificare come flag al g++ <strong><em>-std=c++0x<br />
</em></strong></li>
<li>Inoltre bisogna aggiungere <strong>-lpthread </strong>per usare la lib dei pthread</li>
<li>se continua a non funzionare bisogna installare<strong> </strong>verificate che sia installato anche <strong>gcc-multilib</strong></li>
<li>se ancora continua a non funzionare e vi da errori del tipo<strong><em> </em>fatal error: asm/errno.h </strong>allora l&#8217;installatore non ha fatto il suo dovere e dovete correggere a mano il nome di una cartella:</li>
</ul>
<p style="padding-left: 30px;">andate su <strong>/usr/include/</strong> e controllate che esista la cartella asm-generic, se esiste fatene un link software su <strong>/usr/include/asm</strong> (NON rinominatela, non si sa mai che può succedere con un aggiornamento di pacchetti ) se non esiste e non avete ancora risolto&#8230; mi dispiace ma non so che dirvi, non sono partito da un sistema vergine e quindi non ho verificato tutte le necessità del programma&#8230; scrivetemi nei commenti e cerchiamo una soluzione.</p>
<p><strong><em> </em></strong>E per questo articolo è tutto, continuerò la prossima volta parlando della gestione delle risorse condivise e degli strumenti di sincronizzazione, la parte più divertente deve ancora arrivare <img src='http://www.thedarshan.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<span id="more-722"></span></p>
<h3>E voi lo sapevate che un articolo condiviso su facebook senza un immagine di anteprima viene cliccato molto meno?</h3>
<p>chiudo con un immagine parzialmente appropriata per far fare l&#8217;anteprima a facebook <img src='http://www.thedarshan.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<div class="wp-caption aligncenter" style="width: 310px"><img class=" " title="Thread e processi" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/Multithreaded_process.svg/500px-Multithreaded_process.svg.png" alt="" width="300" height="283" /><p class="wp-caption-text">Lo spazio di indirizzamento di un Thread è interno a quello del processo padre, ma questo lo sapevate già, per il resto questa immagine potrebbe essere pure fuorviante visto che descrive dei thread software xD</p></div>
<p>Questo post fa parte di una serie, gli altri post riguardanti il Cpp0X sono:</p>
<ul>
<li><a title="Permalink to Il C++ non è ancora morto" href="../2011/02/il-c-non-e-ancora-morto/">Il C++ non è ancora morto</a></li>
<li><a title="Permalink to il C++ e le lambda ( C++0X)" href="../2011/03/il-cp-e-le-lambda-c0x/">il C++ e le lambda (      C++0X)</a></li>
<li><a title="Permalink to Il C++ e il Multithreading (C++0X)" href="../2011/10/il-c-e-il-multithreading-c0x/">Il C++ e il      Multithreading (C++0X)</a></li>
<li><a title="Permalink to Sincronizzazione dei Thread e gestione delle risorse con i Mutex ( C++0X)" href="../2011/10/sincronizzazione-dei-thread-e-gestione-delle-risorse-con-i-mutex-c0x/">Sincronizzazione      dei Thread e gestione delle risorse con i Mutex ( C++0X)</a></li>
<li><a title="Permalink to Uso avanzato dei Mutex, i 5 Filosofi (C++0x)" href="../2011/11/uso-avanzato-dei-mutex-i-5-filosofi-c0x/">Uso      avanzato dei Mutex, i 5 Filosofi (C++0x)</a></li>
<li><a title="Permalink to le Condition, implementazione delle code di attesa. il problema del barbiere addormentato (C++0x)" href="../2011/11/le-condition-implementazione-delle-code-di-attesa-il-problema-del-barbiere-addormentato-c0x/">Le      Condition, implementazione delle code di attesa. il problema del barbiere      addormentato (C++0x)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/il-c-e-il-multithreading-c0x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Una classe Java per effettuare il backup di un database Mysql (v 2.0)</title>
		<link>http://www.thedarshan.com/informatica/una-classe-java-per-effettuare-il-backup-di-un-database-mysql-v-2-0/</link>
		<comments>http://www.thedarshan.com/informatica/una-classe-java-per-effettuare-il-backup-di-un-database-mysql-v-2-0/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 17:52:12 +0000</pubDate>
		<dc:creator>Vincenzo La Spesa</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[BufferedOutputStream]]></category>
		<category><![CDATA[BufferedReader]]></category>
		<category><![CDATA[completa]]></category>
		<category><![CDATA[costraint]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[foreign key]]></category>
		<category><![CDATA[funzione]]></category>
		<category><![CDATA[integrità referenziale]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[java.util.zip]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqldump]]></category>
		<category><![CDATA[oggetto]]></category>
		<category><![CDATA[ZipOutputStream]]></category>

		<guid isPermaLink="false">http://www.thedarshan.com/?p=680</guid>
		<description><![CDATA[Quando si sviluppa un applicazione che permette di interagire e modificare un database può essere utile prevedere una funzione che permetta di effettuare velocemente e con un solo click il backup completo dell&#8217;intero database (dati, struttura, trigger e stored procedure). Questa classe fa esattamente questo, e a differenza dei molti snippet che si trovano sul &#8230;  <a class="continue_reading" href="http://www.thedarshan.com/informatica/una-classe-java-per-effettuare-il-backup-di-un-database-mysql-v-2-0/">Continua la lettura &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.thedarshan.com/wp-content/uploads/2011/06/java_blu.png"><img class="alignleft size-full wp-image-681" title="java_blu" src="http://www.thedarshan.com/wp-content/uploads/2011/06/java_blu.png" alt="" width="150" height="126" /></a>Quando si sviluppa un applicazione che permette di interagire e modificare un database può essere utile prevedere una funzione che permetta di effettuare velocemente e con un solo click il backup completo dell&#8217;intero database (dati, struttura, trigger e stored procedure).</p>
<p>Questa classe fa esattamente questo, e a differenza dei molti snippet che si trovano sul web è completa e autosufficente e documentata con javadoc, necessita soltanto della presenza nel sistema del comando &#8220;mysqldump&#8221; (presenza che viene verificata dalla classe stessa).</p>
<p>La classe avvia un istanza di mysqldump e permette di salvarne l&#8217;output in dei file di testo ,in un unico file zip o eventualmente in una stringa</p>
<p>A differenza della versione precedente ( <a href="http://www.thedarshan.com/2009/02/una-classe-java-per-effettuare-il-backup-di-un-database-mysql/">descritta qui</a> )  questa versione permette di importare/esportare anche tabelle che hanno vincoli di integrità relazionale.<br />
Per fare questo disabilita il check delle Costraint , esegue l&#8217;intera importazione all&#8217;interno di una transazione, e poi le riattiva.<br />
Questo comportamento può essere attivato con <strong>checkConstraint</strong>=<em><strong>false<br />
</strong></em>Il comportamento di default è identico alla versione precedente</p>
<p>il file può essere scaricato da <a href="http://www.thedarshan.com/home/files/MysqlBackup.java">QUI</a></p>
<p>vediamo un esempio di utilizzo:</p>
<pre class="brush: java; title: ; notranslate">
package cavia;

import darshan.util.MysqlBackup;
public class Main {

 public static void main(String[] args) {
 MysqlBackup b= new MysqlBackup(&quot;127.0.0.1&quot;, &quot;3306&quot;, &quot;root&quot;, &quot;root&quot;, &quot;darshan&quot;);
 b.checkConstraint=false;
 b.all_to_zip(&quot;/home/darshan/Scrivania/post/dump.zip&quot;);
 System.out.println(&quot;Done&quot;);
 }
</pre>
<p>la classe viene istanziata con <strong>MysqlBackup</strong>(ip, porta, user, password, database) , poi con b.<strong>checkConstraint</strong>=false; disabilito il check delle costraint e con <strong>all_to_zip</strong> eseguo il dump in un file zip, per le altre funzioni affidatevi al javadoc che trovate anche <a href="http://www.thedarshan.com/home/files/MysqlBackup.html">qui</a><br />
<span id="more-680"></span>di seguito il sorgente</p>
<pre class="brush: java; title: ; notranslate">
package darshan.util;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 * @author Vicenzo La Spesa
 * @version 2.0
 * 14/06/2011
 * http://www.thedarshan.com
 */
public class MysqlBackup {

    private static String head=&quot;SET AUTOCOMMIT=0; SET FOREIGN_KEY_CHECKS=0;\n&quot;;
    private static String tail=&quot;SET FOREIGN_KEY_CHECKS=1;COMMIT;SET AUTOCOMMIT=1;\n&quot;;

    /**
     * permette di abilitare/disabilitare il controllo dell'integrità referenziale
     * durante la fase di creazione, nel caso sia disabilitata è possibile inserire
     * tabelle che hanno riferimenti in qualsiasi ordine.
     */
    public boolean checkConstraint=true;

    private String host, port, user,password, db;

 /**
  * boolean installed()
  * verifica se è possibile avviare mysqldump,&lt;br&gt;
  * La verifica viene effettuata avviando &quot;mysqldump --help&quot; e cercando la stringa
  * &quot;mysqldump al suo interno&quot;
  * @return true se il comando è disponibile, false altrimenti
  */
 public boolean installed(){
        try {
            Process run = Runtime.getRuntime().exec(&quot;mysqldump --help&quot;);
            InputStream in = run.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String out = br.readLine();
            int n=out.indexOf(&quot;mysqldump&quot;);
            br.close();
            in.close();
            if(n &gt;-1 &amp;&amp; n&lt;2) return true;
        } catch (IOException ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
        }
    return false;
 }

 /**
  * @param host
  * @param port
  * @param user
  * @param password
  * @param db
  * @return una stringa con il backup del database, &lt;br&gt; una stringa vuota se scrive sullo stream
  * @throws java.lang.Exception
  *
  * esegue il backup dei dati su stringa,o su uno stream dato come argomento &lt;br&gt;
  * è un overload
  */
 private String getData(String host, String port, String user,
                        String password, String db) throws Exception{
     return getData(host, port, user, password, db,null);

 }
 private String getData(String host, String port, String user,
                        String password, String db, OutputStream stream) throws Exception {
  Process run = Runtime.getRuntime().exec(
                       &quot;mysqldump --host=&quot; + host + &quot; --port=&quot; + port +
                       &quot; --user=&quot; + user + &quot; --password=&quot; + password +
                       &quot; --compact --complete-insert --extended-insert &quot; +
                       &quot;--skip-comments --skip-triggers &quot; + db);
  InputStream in = run.getInputStream();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));
  StringBuilder temp = new StringBuilder();
  DataOutputStream output=new DataOutputStream(stream);

  String buffer;

  if(!checkConstraint)output.writeBytes(head);
  while ((buffer = br.readLine()) != null) {
      if(stream!=null){
            output.writeBytes(buffer+&quot;\n&quot;);
      }else{
                temp.append(buffer).append(&quot;\n&quot;);
      }

  }
  if(!checkConstraint)output.writeBytes(tail);

  br.close();
  in.close();

  return temp.toString();//se scrive sullo stream è una stringa vuota
 }

 /**
  *
  * @param host
  * @param port
  * @param user
  * @param password
  * @param db
  * @return una stringa con la struttura del db
  * @throws java.lang.Exception
  *
  * estrae la struttura del db e le stored procedure
  */
 static private String getRoutine(String host, String port, String user,
                           String password, String db) throws Exception {
  Process run = Runtime.getRuntime().exec(
                       &quot;mysqldump --host=&quot; + host + &quot; --port=&quot; + port +
                       &quot; --user=&quot; + user + &quot; --password=&quot; + password +
                       &quot; --compact --no-create-info &quot; +
                       &quot;--no-data --routines &quot; + db);
  InputStream in = run.getInputStream();
  BufferedReader br = new BufferedReader(new InputStreamReader(in));

  StringBuilder temp = new StringBuilder();

  String buffer;

  while ((buffer = br.readLine()) != null) {
            temp.append(buffer).append(&quot;\n&quot;);
      }

  br.close();
  in.close();

  return temp.toString();
 }

    public MysqlBackup(String host, String port, String user,
                           String password, String db) {
        this.host=host;
        this.port=port;
        this.user=user;
        this.password=password;
        this.db=db;
    }

    /**
     * @throws java.lang.Exception
     *
     * Wrapper di getData
     * &lt;strong&gt;
     * LA FUNZIONE NON È OTTIMIZZATA E ALLOCA MOLTA RAM &lt;BR&gt;
     * SERVE SOLO PER FARE TEST
     * &lt;/strong&gt;
     */
    public String data_to_string() throws Exception{
        return getData(host, port, user, password, db);
    }

    /**
     *
     * Wrapper di getRoutine()
     * @throws java.lang.Exception
     */
    public String routine_to_string() throws Exception{
        return getRoutine(host, port, user, password, db);
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * Scrive i dati su un file, funzione ottimizzata per allocare meno ram
     */
    public boolean data_to_file(String nomefile) {
        File filedst = new File(nomefile);
        try {
            FileOutputStream dest = new FileOutputStream(filedst);
            getData(host, port, user, password, db, dest);
            dest.flush();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * Scrive i dati su un file
     */
    public boolean routine_to_file(String nomefile){
        File filedst = new File(nomefile);
        try {
            FileOutputStream dest = new FileOutputStream(filedst);
            dest.write(routine_to_string().getBytes());
            dest.flush();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }

    /**
     *
     * @param nomefile
     * @return true se va bene, false altrimenti
     * genera un file zip con all'interno due files: &lt;br&gt;
     * data.sql con i dati &lt;br&gt;
     * routine.sql con la struttura e le procedure
     */

    public boolean all_to_zip(String nomefile){
        try {
            File filedst = new File(nomefile);
            FileOutputStream dest = new FileOutputStream(filedst);
            ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(dest));
            zip.setMethod(ZipOutputStream.DEFLATED);
            zip.setLevel(Deflater.BEST_COMPRESSION);
            zip.putNextEntry(new ZipEntry(&quot;data.sql&quot;));
            getData(host, port, user, password, db, zip);
            zip.putNextEntry(new ZipEntry(&quot;routine.sql&quot;));
            zip.write(routine_to_string().getBytes());
            zip.close();
            dest.close();
        } catch (Exception ex) {
            Logger.getLogger(MysqlBackup.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.thedarshan.com/informatica/una-classe-java-per-effettuare-il-backup-di-un-database-mysql-v-2-0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

