•  
  • Archivi per luglio 2009 (5)

Hardware – I connettori

Categorie: Web Radio
Tag: Nessun tag
Commenti: 3 commenti
Pubblicato il: 29 luglio 2009

Settantaduesimo articolo dedicato alle web radio

Una delle tantissime critiche che gli amici che mi seguono nella creazione dei miei articoli mi fanno, è quella di dedicarmi ed essermi dedicato pochissimo all’hardware.

Nel cercare di colmare questa lacuna, cominciamo parlando della cosidetta “cavetteria” ossia i connettori.

I connettori più usati in ambito audio, e che troviamo praticamente sempre in qualsiasi web radio più complessa di un semplice winamp + dsp + server shoutcast, sono questi:

  • Connettore RCA
  • Connettore JACK
  • Connetore XLR

RCAIl connettore RCA è uno dei connettori più usati per audio semiprofessionale. Il connettore RCA è mono, viene cablato su cavo coassiale e può trasportare un solo canale alla volta.

Nel caso più comune, il cavo è di tipo maschio/maschio, con una spina a ogni estremità. Un eventuale cavo di prolunga è di tipo maschio/femmina, con presa volante su un’estremità del cavo.

Il connettore è composto da una protuberanza centrale (maschio) o da un foro (femmina), circondati da un anello, separati da un isolante di plastica o ceramica. Il bloccaggio della connessione non è meccanico, ma avviene a pressione, sfruttando la piccola differenza di diametro dell’anello esterno.

Da notare che, a differenza di connettori professionali come il tipo XLR, il polo centrale viene in contatto con l’altro connettore prima della massa, per cui accade spesso che durante la connessione si verifichino ronzii o soffi se questa avviene ad apparecchiature accese.
Connettori audio RCA.

Nel cablaggio di apparati audio, questo connettore si trova frequentemente in configurazioni a Jack-Doppio RCA, che permette di collegare un lettore CD o un PC ad un Mixer; in questo caso i connettori RCA sono colorati in modo diverso, per distinguere il canale destro dal sinistro, il destro è solitamente rosso, mentre il sinistro può essere sia bianco che nero.

(Fonte: Wikipedia)

JACK
Il connettore jack è senza alcun dubbio il connettore più usato per la connettività delle piccole apparecchiature audio. Si distinguono abitualmente tre tipi di connettori jack secondo il diametro :

* Jack 2.5 mm: il più piccolo jack,
* Jack 3.5 mm: il jack classico, corrispondente alla presa cuffia,
* Jack 6.35 mm: il jack usato per la sonorizzazione semi-professionale per collegare gli altoparlanti, gli amplificatori o i microfoni.

Ognuno di questi jack si declina in due versioni :

* jack mono, per le trasmissioni di un suono monofonico. Questo tipo di jack possiede due contatti : una referenza, sul corpo della fiche, e il segnale sulla punta.
* jack stereo, per la trasmissione di un suono stereofonico. Questo tipo di jack possiede tre contatti, cioè gli stessi contatti che il connettore jack nonché un anello supplementare che permette la trasmissione di un altro canale audio.

Questo connettore dispone di tre contatti e quindi può realizzare connessioni audio sbilanciate con 2 canali (sinistro e destro) e connessioni audio bilanciate ad 1 canale.

Il connettore JACK offre un buon contatto elettrico, una buona resistenza meccanica e una pessima resistenza alla trazione.

(Fonti: Dreamvideo, kioskea)

XLRIl connettore XLR fu prodotto per la prima volta negli Stati Uniti dalla Cannon Electric, la sigla XLR deriva dal nome originale Cannon X , a cui furono aggiunte prima un blocco (Latch) di sicurezza, e poi un isolante di gomma (Rubber) attorno ai poli. La sigla XLR è a volte interpretata come “eXtra Long Run”. Un connettore XLR può avere diversi schemi di piedinatura, i tipi più comuni sono a tre, quattro e cinque poli.

Nella sua versione a tre poli, il connettore XLR viene usato normalmente per la terminazione di linee audio bilanciate, ma spesso viene usato anche per segnali sbilanciati creando un corto circuito tra il polo di massa e quello freddo. È praticamente l’unico tipo di connettore impiegato per il collegamento di microfoni, mentre per i segnali a livello di linea è più comunemente usato il jack stereo.

Bisogna fare attenzione alle apparecchiature che usano il polo 3 come caldo, perché può capitare facilmente di invertire la polarità del segnale audio.

Sempre la versione tripolare viene usata per le connessioni audio di tipo digitale: in questo caso il sistema di modulazione usato non pone problemi nel caso di connessioni in controfase.

(Fonte: Wikipedia)

Bourne Again Shell – Bash – Introduzione e alcuni script di prova

Categorie: Informatica, Ingegneria
Tag: Nessun tag
Commenti: Nessun Commento
Pubblicato il: 7 luglio 2009

BASH!Uno dei vari argomenti del corso di sistemi operativi, è lo scripting in ambiente unix. Quello che si studia nel mio corso di laurea è la bash, incentrandosi abbastanza sulle regex.

Qui di seguito proporremo e commenteremo alcuni semplici codici bash per automatizzare delle operazioni, li commenteremo e, permettetemelo, che Dio me la mandi buona…

Rinvio tutti a leggere la pagina di wikipedia per maggiori info storico/letterarie.

Prenderò spunto dal sito http://www.pluto.it/files/ildp/HOWTO/Bash-Prog-Intro-HOWTO/Bash-Prog-Intro-HOWTO.html per gli script di esempio riportati

1
2
              #!/bin/bash
              echo Hello World

Questo script ha solamente due righe. La prima indica al sistema quale programma utilizzare per eseguire il file. La seconda riga è l’unica azione compiuta dallo script, che stampa ‘Hello World’ sul terminale tramite il comando echo.

1
2
3
 #!/bin/bash
                STR="Hello World!"
                echo $STR

La riga 2 crea una variabile chiamata STR e le assegna la stringa “Hello World!”. Poi il VALORE di questa variabile è recuperato inserendo il simbolo ‘$’ all’inizio.

Threads, Mutex e Semafori in C – La programmazione concorrente – Semafori

Categorie: Informatica
Tag: Nessun tag
Commenti: Nessun Commento
Pubblicato il: 4 luglio 2009

SemaforoContinuiamo la trattazione della programmazione concorrente presentando un altro listato recuperato su internet che possa stavolta mostrarci come funzionano e lavorano i semafori.

I semafori sono una struttura dati che permette la gestione della mutua esclusione tra processi o nel nostro caso tra threads dello stesso processo. Informazioni più complete sui semafori sono disponibili su wikipedia. Noi ci limiteremo ad esaminare del codice sorgente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
 
/*!
mainpage Esempio Semafori con Pthreads
section intro Introduzione
Esempio di utilizzo semafori
 
date 10/05/2006
version   23.24 04/07/2009
author    A.Dal Palu
*/
 
 
 
static sem_t s1,s2;  /// semafori
 
 
 
/*!
    brief  Codice del thread1
 
    Il thread fa Ping e fa UP sul semaforo dell`altro thread
*/
void *thread1(void * arg)
{
  int i;
  for (i=0;i<10;i++){
    sem_wait(&s1);
    printf("Pingn");
    sem_post(&s2);
  }
  printf("T1 exitn");
  pthread_exit (0);
}
 
 
/*!
    brief  Codice del thread2
 
    Il thread fa Pong e fa UP sul semaforo dell`altro thread
*/
void *thread2(void * arg)
{
  int i;
  for (i=0;i<10;i++){
    sem_wait(&s2);
    printf("Pongn");
    sem_post(&s1);
  }
  printf("T2 exitn");
  pthread_exit (0);
}
 
 
int main()
{
  pthread_t tid1,tid2;
  void * ret;
 
  sem_init(&s1,0,1);
  sem_init(&s2,0,0);
 
  if (pthread_create(&tid1, NULL, thread1, NULL) < 0)
    { fprintf (stderr, "pthread_create error for thread 1n");
    exit (1);
    }
 
  if (pthread_create(&tid2, NULL, thread2, NULL) < 0)
    { fprintf (stderr, "pthread_create error for thread 2n");
    exit (1);
    }
 
  pthread_join (tid1, &ret);
  pthread_join (tid2, &ret);
 
  printf("Exitn");
}

Il programma è composto da tre funzioni:thread1, thread2 e il main.

Una volta inseriti gli include e inizializzato le variabili, i semafori, possiamo procedere allo studio del main.

Il main crea i thread, e una variabile d’appoggio chiamata ret, che è un puntatore a void. Dopodichè inizializza i semafori creati e i thread stessi.

Effettua anche il join dei thread e alla fine termina.

La funzione thread1, invece, effettua un altro tipo di operazioni.

La funzione sem_wait sospende il thread chiamante fintanto che il valore del semaforo puntato dall’argomento è diverso da zero. Viene inoltre decrementato automaticamente, ed atomicamente, il contatore. Questo significa che settando il valore del semaforo ad 1 ed effettuando questa chiamata il processo non si arresterà.

Successivamente viene stampato il ping e dopo parte la sem_post.

Al contrario della precedente questa funzione semplicemente incrementa il valore del semaforo passato come parametro. Qualora questo semaforo avesse già raggiunto il massimo numero consentito viene ritornato -1 mentre la variabile ERRNO viene settata ad EINVAL. In caso di successo, invece, viene restituito 0.

Esaminiamo dei possibili scenari di compilazione.

Il codice per come è scritto se viene compilato ed eseguito, restituisce un output del genere:

Ping
Pong
Ping
Pong
Ping
Pong
Ping
Pong
Ping
Pong

T1 exit
Pong
T2 exit
Exit

Questo perchè? Perchè il primo dei due semafori ha come valore iniziale 1. Se si modificano i valori reciproci dei semafori, la situazione cambia non poco.

Ricordiamo intanto quali sono le operazioni che vengono fatte dalle funzioni. All’interno della funzione thread1, che è la prima ad essere invocata, la sem wait diminuisce il valore del semaforo, che non è 0, e per questo il thread non si blocca. Esegue quello che deve eseguire, e invoca la sem post sull’altro thread, che passa da 0 (valore iniziale) a 1.

Il gioco si ripete per il thread 2, proprio come il ping pong ;)

Cosa succede nei casi in cui:
1) I due semafori partono entrambi da 0
2) Il primo parte da 0 e il secondo da 1
3) Partono entrambi da 1
4) Il primo ha un valore molto superiore al secondo
5) Entrambi partono da N

Esaminiamo caso per caso, prima logicamente, poi compilando e vedendo se avevamo ragione o meno…

Se T1 e T2 partono da 0 cosa succede? Viene sempre invocata thread1 per prima, che invoca la wait che incontra un semaforo con valore 0 e blocca il thread. Il quanto finisce e viene fatto lavorare il thread2, che non può non avere lo stesso destino perchè anche lui parte da 0, morale della favola: Deadlock!

Se T1 parte da 0 e T2 parte da 1 cosa succede? Semplicemente il flusso si inverte, e si parte con Pong, piuttosto che con Ping.
Pong
Ping
Pong
Ping
Pong
Ping
Pong
Ping
Pong
Ping

T1 exit
T2 exit
Exit

Questo perchè PRIMA viene eseguita una wait su un semaforo a valore 0.

Se T1 parte da 1 e T2 parte da 1 cosa succede? Non cambia nulla rispetto al partire t1 con 0 e t2 con 0, in quanto comunque t1 avrebbe incrementato t2 prima di terminare la sua esecuzione per cui alla fine, il comportamento è lo stesso.

Se t1 è molto maggiore di t2 in valore iniziale? Semplicemente si vedranno tanti PING consecutivi in base al numero di partenza del semaforo, perchè il ciclo chiamerà sem_wait decrementando un numero che non diventerà 0 prima delle N volte impostate inizialmente. Dopo il ciclo continuerà con un ping pong, fintantochè non si esaurisce il ciclo del primo thread, che muore, e ci saranno da allora solo pong.

Se t1 e t2 partono da N cosa succede? Caso da considerarsi identico al precedente.

Threads, Mutex e Semafori in C – La programmazione concorrente – Mutua esclusione

Categorie: Informatica
Tag: Nessun tag
Commenti: Nessun Commento
Pubblicato il: 4 luglio 2009

filosofi a tavolaAbbiamo esaminato un listato inerente la programmazione concorrente, ma, obiettivamente, il listato presentato è puramente accademico, in quanto non solo non reputo personalmente utile utilizzare due thread per una printf, ma non credo sarebbe servito direttamente il programma.

Fatta questa (dovuta) premessa, continuiamo la trattazione facendo vedere il REALE motivo per cui si lavora in programmazione concorrente, ovvero l’accesso alla memoria condivisa.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX 10
 
pthread_mutex_t M; /* def.mutex condiviso tra threads */
 
int DATA=0; /* variabile condivisa */
 
int accessi1=0; /*num. di accessi del thread 1 alla sez critica */
int accessi2=0; /*num. di accessi del thread 2 alla sez critica */
 
void *thread1_process (void * arg)
{ int k=1;
 while(k)
   {
     pthread_mutex_lock(&M); /*prologo */
     accessi1++;
     DATA++;
     k=(DATA>=MAX?0:1);
     printf("accessi di T1: %dn", accessi1);
     pthread_mutex_unlock(&M); /*epilogo */
     sleep(1);
   }
 pthread_exit (0);
}
 
void *thread2_process (void * arg)
{ int k=1;
 while(k)
   {
     pthread_mutex_lock(&M); /*prologo sez. critica */
     accessi2++;
     DATA++;
     k=(DATA>=MAX?0:1);
     printf("accessi di T2: %dn", accessi2);
     pthread_mutex_unlock(&M); /*epilogo sez. critica*/
     sleep(1);
   }
 pthread_exit (0);
}
 
int main ()
{ pthread_t th1, th2;
/* il mutex e` inizialmente libero: */
 pthread_mutex_init (&M, NULL);
 if (pthread_create(&th1, NULL, thread1_process, NULL) < 0)
   { fprintf (stderr, "create error for thread 1n");
   exit (1);
   }
 if (pthread_create(&th2, NULL,thread2_process,NULL) < 0)
   { fprintf (stderr, "create error for thread 2n");
   exit (1);
   }
 pthread_join (th1, NULL);
 pthread_join (th2, NULL);
 
 printf("Accessi: T1: %d, T2 %dn",accessi1,accessi2);
}

Commentiamo il codice dall’inizio.

La priam parte è scontata, sono gli include, chi vuole vederseli vada pure qui. Dopo, definiamo una macro, che attribuisce a MAX il valore dieci per tutto il programma. (Adoro le macro di sostituzione, permettono al C di trasformarsi in qualsiasi cosa )

inizializziamo un MUTEX, tramite la variabile pthread_mutex_t, mentre DATA rappresenterà la nostra variabile condivisa. Accessi1 e Accessi2 ci mostreranno il numero di volte che i due threads accederanno alla memoria condivisa.

Cominciamo con le funzioni, che sono molto simili tra di loro come struttura, ma agiscono su variabili diverse in alcune parti.

La funzione *thread1_process inizializza una variabile k, ponendola pari ad 1, e crea un ciclo while con k funzione chiusura del ciclo.

Il ciclo è composto da:

* Lock del mutex tramite la funzione pthread_mutex_lock che accetta come argomento un riferimento ad un mutex.
* incremento degli accessi del thread e della variabile DATA
* Se data ha raggiunto il valore massimo allora il flag k diventa zero e il ciclo non si ripeterà.
* Stampa del numero di accessi
* Sblocco del mutex

Anche *thread2_process esegue un ciclo identico.

Il main alla fine effettua le seguenti operazioni:

* Crea due thread
* Inizializza il mutex creato, che inizialmente è libero
* Lancia la create per i due thread e su entrambi effettua un controllo d’errore.
* Effettua il join dei due threads

Threads, Mutex e Semafori in C – La programmazione concorrente

Categorie: Informatica
Tag: Nessun tag
Commenti: Nessun Commento
Pubblicato il: 2 luglio 2009

Threads!Ebbene si, sono tornato a studiare.

Dopo il tormento elettrotecnica, si passa a sistemi operativi, una materia molto bella ma molto ostica, che mi “costringerà” nel poco tempo che ho a disposizione, a studiare la programmazione concorrente in C.

Chiunque mi conosca un minimo, sia tramite il mio blog che di presenza, sa che non sono un eccellente programmatore, specialmente in C, anche se mi piace abbastanza programmare, quando mi ci metto.

Tempo fa parlai di alberi binari, adesso parliamo di thread.

Un thread è la più piccola unità di utilizzo della CPU, contenuta all’interno di un processo, che può agire contemporaneamente ad altri thread, chiamati appunto concorrenti.

Un linguaggio di programmazione che fa uso di threads, è detto concorrente.

Non scendo al momento nel dettaglio sul perchè i threads siano utili e a cosa servano.. vediamo qualche semplice esempio di listati sui threads, ovvero come crearli, joinarli e distruggerli, ma soprattutto, come farli cooperare.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include
#include
 
void *funzionebanale1(void * arg)
{
printf ("Thread numero 1 in azionen");
pthread_exit (0);
}
void *funzionebanale2(void * arg)
{
printf ("Thread numero 2 in azionen");
pthread_exit (0);
}
 
int main(void * args)
{
pthread_t tid1, tid2;
pthread_create(&tid1,NULL,funzionebanale1,NULL);
pthread_create(&tid2,NULL,funzionebanale2,NULL);
pthread_join (tid1, NULL);
printf("terminato il thread 1n");
pthread_join (tid2, NULL);
printf("terminato il thread 2n");
return 0;
}

Vediamo di esaminare un pò questo listato.

La prima parte, gli include, sono più che noti a chi ha un minimo di dimestichezza con il linguaggio C, andiamo quindi immediatamente alla parte successiva.

Quello che vediamo sono due funzioni molto semplici (non per niente chiamate funzionibanali) che restituiscono un puntatore a void, e che accettano un puntatore a void come argomento.

Le funzioni si limitano a stampare a video una scritta con una semplice printf e a richiamare una funzione, chiamata pthread_exit con parametro 0, che permette di chiudere un thread senza rilasciare errori.

Andiamo quindi al main.

Un thread va INIZIALIZZATO come una qualsiasi variabile, in questo caso il tipo è pthread_t, per cui creiamo due threads, chiamandoli tid1 e tid2.

A questo punto possiamo effettivamente creare il thread vero e proprio, utilizzando la funzione pthread_create

La funzione pthread_create accetta quattro argomenti, il primo è un riferimento alla variabile pthread_t su cui si lavora, il secondo è invece un riferimento ad una variabile di tipo pthread_attr_t che identifica gli attributi che deve avere il thread. Impostando tale secondo attributo a NULL, si utilizzeranno i valori di default, caso abbastanza classico.

Il terzo attributo rappresenta un puntatore alla funzione che contiene il codice che deve eseguire il thread.

Il quarto attributo rappresenta l’attbuto che viene passato alla funzione precedentemente puntata. Se la funzione può anche non accettare argomenti, si può impostare un simpatico NULL.

Una volta creati i due thread, occorre joinare.

La funzione pthread_join sospende l’esecuzione del thread chiamante fintantochè non è completato il codice del thread chiamato. La funzione accetta come argomenti un thread e un puntatore doppio, nella quale variabile puntata sarà inserito il valore di ritorno del thread chiamato.

pagina 1 di 1
Seguimi
FacebookLinkedInTwitterYoutubeRSS
I like it!
Google and Twitter

Benvenuto , oggi è lunedì, 6 febbraio 2012