Autore Topic: Sensori e multithreading  (Letto 2207 volte)

Offline Rosekarma84

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
Sensori e multithreading
« il: 09 Ottobre 2014, 13:36:03 CEST »
0
Buongiorno a tutti.
Devo sviluppare un'applicazione multithreading per il rilevamento di dati dai vari sensori dello smartphone e ho bisogno di aiuto, ossia di qualche idea perché non so proprio da che parte cominciare.
Il professore mi ha chiesto di fare in questo modo: ho una coda circolare a cui un thread (che si registra come SensorEventListener ad esempio sull'accelerometro) accede in scrittura e salva ad esempio i dati dell'accelerometro degli ultimi 10 secondi. Questo thread non si ferma mai, cioè deve continuare costantemente a sensire i dati e ad inserirli in questa coda circolare.
Un secondo thread invece deve periodicamente (ad esempio ogni 10 secondi) trasferire i dati dalla coda in un file, e quindi ha bisogno di accedere alla coda in lettura. Naturalmente quest'ultimo thread non deve scrivere sul file campioni che ha già salvato precedentemente.
Inoltre altri thread in futuro (cioè appartenenti ad altre classi  potrebbero avere la necessità di accedere in lettura alla suddetta coda.
In pratica, se non ho capito male, dovrei sincronizzare i thread tra loro mediante un meccanismo di tipo semaforico, ma non so bene come procedere e vorrei che qualcuno mi desse qualche spunto, a grandi linee, sul tipo di struttura dati da utilizzare .
Potreste darmi qualche suggerimento per favore?

Grazie a tutti in anticipo

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Sensori e multithreading
« Risposta #1 il: 09 Ottobre 2014, 13:49:06 CEST »
0
Non per non risponderti, ma queste problematiche sono relative alla programmazione concorrente in Java, cioè non hanno sostanzialmente niente a che vedere con Android tranne che per l'uso del sensore. Tutta la problematica multi-thread, coda circolare e sincronizzazione nell'accesso a dati condivisi, riguarda solo la programmazione Java (che non viene trattata in questo forum).

Comunque, puoi trovare spunti cercando keywords come "java" e "concurrency".
Lesson: Concurrency (The Java™ Tutorials > Essential Classes)
Java concurrency (multi-threading) - Tutorial
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Sensori e multithreading
« Risposta #2 il: 09 Ottobre 2014, 13:59:57 CEST »
0
Ma scusate... quando io registro un listener mi viene richiamato il metodo finchè non lo deregistro.
A che serve far partire un thread per poi attaccarci un listener? Non ha senso.

Capisco che il professore lo voglia così, ma non vedo una ragione valida per attaccare un listener ad un thread.
Il thread servirebbe se la lettura avvenisse manualmente da una porta: hai un while e continui a fare polling dei dati.

Ma il meccanismo del listener in teoria serve proprio ad eliminare la necessità di crearsi un thread apposito.

Sbaglio io?

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Sensori e multithreading
« Risposta #3 il: 09 Ottobre 2014, 14:41:53 CEST »
0
Sbaglio io?

Secondo me non sbagli, ma (per come l'ho capito) lo scopo non è l'app android. Lo scopo è didattico e riguarda la programmazione concorrente in Java, con sincronizzazione, semafori, accesso a dati condivisi, etc. Lo stesso identico codice potrebbe essere scritto e testato in Java su desktop, ma chiaramente l'ambiente android rende (giustamente) tutto più accattivante e pratico. Tutto qua.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Rosekarma84

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
Re:Sensori e multithreading
« Risposta #4 il: 09 Ottobre 2014, 16:06:58 CEST »
0
Non credevo di sollevare tutto questo polverone, scusate...
comunque un thread può essere esso stesso un SensorEventListener (una classe java può estendere più interfacce) , quindi non si deve attaccare niente da nessuna parte.
Ero semplicemente a cerca di spunti, idee,  ma evidentemente ho cercato nel posto sbagliato.
Chiedo scusa,
buona giornata a tutti

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Sensori e multithreading
« Risposta #5 il: 09 Ottobre 2014, 16:47:38 CEST »
0
Ero semplicemente a cerca di spunti, idee,  ma evidentemente ho cercato nel posto sbagliato.
Chiedo scusa,
buona giornata a tutti

Nessun polverone e nessun problema. Era solo per suggerirti dove poter trovare le risposte e l'aiuto che cercavi.

Ciao
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Sensori e multithreading
« Risposta #6 il: 09 Ottobre 2014, 20:34:12 CEST »
0
Infatti nessun polverone  ;-)

Tutti sappiamo come sono gli esercizi didattici..  :D

Beh per tornare in topic e cercare di darti una mano... fondamentalmente hai ragione: devi creare un thread che implementa un listener.

Il mio dubbio è che il tuo listener viene chiamato quando c'è un nuovo evento del sensore, quindi se lo metti in un thread fondamentalmente il thread deve girare fino a quando per qualsiasi motivo non deicidi di stopparlo. Per quello intendevo dire che è inutile.

Nella run del thread puoi mettere una cosa del tipo:
Codice (Java): [Seleziona]
while(bRunning){
// do nothing!
}

Per il buffer circolare e per i problemi di salvataggio io farei così.
Creerei una classe X che ha un ID evento e i dati del sensore.
Preallochi un arraylist o altra struttura con classi X.
Tieni un contatore per l'indice nell'arraylist (che poi muovi ciclicamente) e un intero per l'evento corrente.
Quando ti arriva il dato dal sensore scrivi nella posizione "intero per evento corrente" i dati del sensore e l'ID evento nella classe. Poi fai ID evento++ e intero per evento corrente++.
Quando intero per evento corrente == arraylist.size() lo rimetti a zero.

Per quanto riguarda il thread di lettura il primo problema è che devi temporizzarla. Cioè se tu fai una lettura ogni secondo magari perdi dati. Se invece fai 1000 letture al secondo potresti non avere nuovi dati da leggere.

Bisogna vedere un attimo quale dimensione deve avere un buffer circolare per tenere tutti i dati a una frequenza di lettura di 10 secondi.

L'uso dei semafori in questo caso lo vedo arduo perché i dati che arrivano sono in tempo reale. Non credo tu possa stoppare l'accesso alla coda in scrittura con un semaforo perché perderesti dati.

ps hai scritto nel posto giusto, scusami se ti ho dato l'impressione di non volerti aiutare o contestarti, non era assolutamente mia intenzione!  :-)


Post unito: [time]09 Ottobre 2014, 21:00:03 CEST[/time]
Mi è venuto in mente ora che se è necessario puoi provare a "simulare" un thread che fa polling.

In teoria potresti implementare il listener in una classe qualsiasi, anche la activity.
Nel tuo thread nel while dentro la run chiami una funzione "getsensordata" che fa il polling. Questa funzione la fai bloccante fino a quando non arriva un nuovo dato dal sensore. Ovviamente il problema è che dovresti sincronizzare il getsensordata con questa funzione che fa polling. A conti fatti però potresti cavartela con una synchronized o con un booleano o altro che puoi assumere essere (o rendere) una operazione atomica. Si tratta di leggere un dato, scriverlo in una variabile e segnalare che un nuovo dato è disponibile pe la getsensordata.

Il vantaggio però è che una volta fatto quello hai un thread di polling e uno che legge ricondotti a una casistica classica e implementare lì i semafori dovrebbe essere più semplice.

 :-)
« Ultima modifica: 09 Ottobre 2014, 21:03:11 CEST da undead »

Offline Rosekarma84

  • Nuovo arrivato
  • *
  • Post: 8
  • Respect: 0
    • Mostra profilo
Re:Sensori e multithreading
« Risposta #7 il: 09 Ottobre 2014, 22:39:01 CEST »
0
Benissimo, adesso ho le idee molto più chiare.
Grazie a tutti

Offline arlabs

  • Utente normale
  • ***
  • Post: 434
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS7
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Sensori e multithreading
« Risposta #8 il: 10 Ottobre 2014, 10:17:35 CEST »
+1
Ma scusate... quando io registro un listener mi viene richiamato il metodo finchè non lo deregistro.
A che serve far partire un thread per poi attaccarci un listener? Non ha senso.

Capisco che il professore lo voglia così, ma non vedo una ragione valida per attaccare un listener ad un thread.
Il thread servirebbe se la lettura avvenisse manualmente da una porta: hai un while e continui a fare polling dei dati.

Ma il meccanismo del listener in teoria serve proprio ad eliminare la necessità di crearsi un thread apposito.

Sbaglio io?

Undead, il metodo registerListener può essere chiamato con un parametro Handler alla fine...
..credo che l'intento sia proprio quello farle chiamate ad un Looper diverso da quello UI (io l'ho usato così)

Se ti serve fare un campionemento di un sensore alla massima velocità (se imposti SENSOR_DELAY_FASTEST, ho visto che c'è una misurazione ogni 5ms) può essere la soluzione.
Come pure se intendi fare qualche elaborazione "pesante" sui segnali... potrebbe essere il modo più semplice per non farla nel thread principale.

Ciao.

Offline undead

  • Utente senior
  • ****
  • Post: 666
  • Respect: +113
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S6
  • Play Store ID:
    DrKappa
  • Sistema operativo:
    Windows 10 64-bit, Windows 8.1 64-bit
Re:Sensori e multithreading
« Risposta #9 il: 10 Ottobre 2014, 11:28:48 CEST »
0
Questa cosa dell'handler mi era sfuggita! Grazie!

Però il mio dubbio rimane, il meccanismo del "listener" viene chiamato sul thread X (UI o non UI che sia) ogni N millisecondi.

In una situazione accademica invece hai un thread che legge da un buffer circolare e un thread che ci scrive. Il thread che scrive gira continuamente e attendendo un nuovo dato, con il comando che fa polling bloccante/non bloccante.

Eliminando la parte in cui fai polling e ricevendo dati ogni N millisecondi hai "risolto" parte del problema classico del multithreading.


Offline arlabs

  • Utente normale
  • ***
  • Post: 434
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS7
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Sensori e multithreading
« Risposta #10 il: 10 Ottobre 2014, 14:56:20 CEST »
0
Vero, sicuramente non è l'esempio più calzante per far esercitare gli studenti col problema produttore-consumatore applicato ai thread.