Newsgroup: it.comp.lang.c++
Titolo: Semplice domanda:

Come evitare il conflitto tra due app. win3.1 che leggono e scrivono lo
stesso file (testo)?
Perdonate se spedisco troppi quesiti, non siete tenuti a rispondere.
P.S. Domani ne ho un'altro sui menu, de non lo risolvo prima!
Ciao, Fulvio

stesso file (testo)?
Per leggerlo non ci sono problemi, ma per scriverlo bisogna che lo
facciano una per volta; l'interblocco temo che te lo devi realizare
da solo, mi sembra che win3.1 non avesse primitive di locking.
E poi chi aggiorna il file dovrebbe notificare l'altra applicazione
in modo che questa si vada a riaprire il file aggiornato.
Potresti mettere il codice che gestisce il tutto in una dll, con una
variabile globale che fa da semaforo.
Questo e' il poco che ricordo, e potrei anche ricordare male...

 stesso file (testo)?
Il "conflitto" è un normale accesso contemporaneo ed è presente solo in
scrittura. Devi fare in modo che questo non avvenga e l'unico modo che
conosco è quello di crearti dei semafori.
EMG

> da solo, mi sembra che win3.1 non avesse primitive di locking.
Aveva lo share.exe che gestiva la concorrenza sui file, e tante funzioni per
l'accesso concorrenziale agli stessi. Un alveare.
Bisogna perň vedere di implementarle.
Credo comunque che se si riesce ad ottenere l'apertura contemporanea del
file, i conflitti non possono accadere, essendo un sistema non-preemptive.
Basta assicurarsi di non andare a scrivere porzioni di files che non si sono
appena lette o che sono cambiate.
Se lavori su record, basta tenere una
copia dell'ultima lettura, e prima di scrivere le nuove informazioni, andare
a rileggerlo per verificare conflitti.
Se lavori su testo, diventa piů complicato, e bisognerebbe sapere cosa ci
fai. Al limite puoi tenerti tutto il file in memoria, o tutta una riga, o
qualcosa del genere.
Tutto ciň ovviamente ha senso nel caso di interfaccie di inserimento dati (e
possibile swap tra le applicazioni). Se le modifiche vengono effettuate
subito dopo la lettura, o tutte in una volta, il problema non sussiste per
il motivo visto prima.
--
Alessandro Monti
P.S.
Forse non era il NG giusto.

 Tutto ciò ovviamente ha senso nel caso di interfaccie di inserimento dati


potrebbe funzionare?
Non credo sia sufficiente (di fatto i semafori sono un po' piu` 
complicati), le due applicazioni potrebbero tentare di accedere
alle risorse contemporaneamente e cio` generalmente si traduce in
disastri...
Usa direttamente i semafori forniti dal s.o. (penso che anche win 3.x
li fornisca).
Paolo
-----------------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
-----------------------------------------------------------------

 potrebbe funzionare?
No. Sposteresti semplicemente il problema dal tuo file al file semaforo.
Temo che un semaforo possa essere implementato solamente dal sistema
operativo di rete. Qualcuno smentisce?
EMG




 potrebbe funzionare?
Si, dato che win3.1 non ha un multitasking preemptive, e quindi nessun altro
programma puň provare a controllare l'esistenza del file nello stesso tempo
in cui lo fai tu (tra il controllo e l'apertura). Assicurati perň di
scrivere le due istruzioni accoppiate, devi essere sicuro che non ci sia un
cambio di contesto (swap delle applicazioni) tra le due.
Non farlo mai perň con altri sistemi operativi realmente multitasking.
Semmai usa questo sistema ora come soluzione veloce, ma studiati anche la
concorrenza. Dopotutto ormai win3.1 non č piů lo standard :)
--
Alessandro Monti

 operativo di rete. Qualcuno smentisce?
Qualsiasi SO multitasking che ci tenga alla concorrenza tra i processi, non
necessariamente di rete.
E a condizione che l'hardware supporti qualche primitiva di
sincronizzazione. Win3.1 non aveva semafori perchč doveva girare (male)
anche sui 286.
--
Alessandro Monti

 usare Globalalloc, ma come lo inserisco?
Bho, dipende.
In C++ c'è l'operatore new
Bisognerebbe anche sapere le dimensioni (almeno previste) del file, giusto
per stabilire un buon metodo di memorizzazione. Credo che un buffer per una
"finestra" di 4k possa adattarsi a tutte le esigenze.
--
Alessandro Monti

 
Dovresti specificare cosa intendi per S.O. "di rete" ?
Marco Guidi 




 Neanche così?
No. Due applicazioni potrebbero controllare l'esistenza del semaforo
prima che questo sia creato e successivamente, non trovandolo, crearlo
entrambe.
EMG

operativo di rete. Qualcuno smentisce?
Qualsiasi s.o. multiprogrammato... anche Linux (presumo) e win95/98/NT
li implementano.


Potresti essere piů chiaro, in cosa consistono?
Un semaforo e` una struttura che serve a sincronizzare
i processi. In pratica e` un oggetto a tutti gli effetti simile
al semaforo che trovi per strada; un processo che vuole accedere
ad una risorsa condivisa deve prima guardare il semaforo associato
alla risorsa per sapere se e` autorizzato o meno ad accedere a quella
risorsa in quel momento o se c'e` qualcun'altro che al momento la tiene
impegnata.
Lo scopo e` evitare che sequenze indivisibili di operazioni sulla 
risorsa condivisa siano interrotte da altre operazioni di altri 
processi.
Naturalmente un semaforo e` esso stesso una risorsa condivisa,
solo che le operazioni sui semafori vengono garantite essere
indivisibili ad hardware (sui sistemi uniprocessor ad esempio
e` sufficiente disabilitare le interruzioni durante le operazioni sui
semafori, sui sistemi multiprocessor invece la situazione e`
piu` complessa).
Una soluzione completamente software esiste (almeno per gli
uniprocessor), ma e` assai costosa in termini di tempo.
Nel caso del file-semaforo, la soluzione puo` funzionare solo
per via di tutta una serie di condizioni tutte verificate
(il multitasking cooperativo e` solo una di queste).


Neanche cosě?
devi garantire che le azioni siano atomiche (cioe` esegute sulla base
del "tutto o niente"), purtroppo le API in generale non ti forniscono
alcuna possibilita` in merito.


 li implementano.
  Beh, pero` in genere i S.O. totalmente orientati verso il modello
  "scambio di messaggi" (le vecchie versioni di Linux per esempio vi si
  avvicinavano molto) non implementano veri e propri semafori (a
  voltem implementano qualcosa di simile impiegando delle receive bloccanti
  per simulare la wait su un semaforo.
 Comunque nelle nuove versioni di Linux dovrebbero essere presenti
 delle implementazioni di semafori, ma credo che possano essere usati
 solo sfruttando il multithreading. In ogni caso la pagina di manuale
di    int sem_init(sem_t *sem, int pshared, unsigned int value);
      int sem_wait(sem_t * sem);
      int sem_trywait(sem_t * sem);
      int sem_post(sem_t * sem);
      int sem_getvalue(sem_t * sem, int * sval);
      int sem_destroy(sem_t * sem);
riporta...
       Semaphores  are  counters  for  resources  shared  between
       threads. The basic operations on semaphores are: increment
       the counter atomically, and wait until the counter is non-
       null and decrement it atomically.
       sem_init initializes the semaphore object  pointed  to  by
       sem.   The count associated with the semaphore is set ini-
       tially to value.  The pshared argument  indicates  whether
       the semaphore is local to the current process ( pshared is
       zero) or is to  be  shared  between  several  processes  (
       pshared is not zero). LinuxThreads currently does not sup-
       port  process-shared  semaphores,  thus  sem_init   always
       returns with error ENOSYS if pshared is not zero.
       Comunque in genere per avere memoria condivisa in sistemi
       come Linux, spesso si usano librerie come Pthreads.
 Marco Guidi

 Dovresti specificare cosa intendi per S.O. "di rete" ?
Come ha precisato Alessandro, intendevo riferirmi a qualunque sistema
che permettesse l'accesso contemporaneo di due applicazioni allo stesso
file.
EMG


Mah?.
Per quanto ne so io comunque i semafori (almeno in senso stretto)
possono essere implementati solo su sistemi del tipo "a memoria condivisa",
mentre non possono essere implementati su sistemi del tipo "a scambio
di messaggi" (e se non e` vero vado dal Prof. di Sistemi Operativi
e mi faccio ridare 3-4 mesi di vita, cioe` quelli che ho passato a studiare
dopo che mi ha valulato un compito nettamente insufficiente per aver 
usato semafori in un sistema a scambio di messaggi :-).
Non so se qualsiasi sistema che consenta l'accesso contemporaneo
a due file debba essere considerato "a memoria condivisa".
Marco Guidi.
 




  avvicinavano molto)
Hai perfettamente ragione, al momento mi sfuggiva il fatto che i
semafori servono per la cooperazione ad ambiente globale.
In un sistema ad ambiente locale le cose cambiano e in effetti i
semafori ammesso che ci siano non sono visibili al programmatore.
Windows mi pare che adotti un sistema misto, nel senso che le
applicazioni scambiano messaggi, ma sono presenti comunque
i semafori per via del multithreading... ma non vorrei sparare eresie!


a due file debba essere considerato "a memoria condivisa".
Se il sistema consente una tale situazione sei per definizione in
ambiente globale.


 di messaggi"
Io non so come vengano implementati i semafori nei sistemi operativi di
rete tipo Novell o W9x ma so che senza di essi non sarebbe possibile
scrivere software per multiutenza.
EMG

  
PGP 2.6.3i key available
--------------------

 Cosě apertura e controllo sono la stessa operazione, a prova di mtask.
Si, mi sembra che questo dovrebbe funzionare. Perň bisogna stare sempre
molto attenti in quanto le problematiche del multiuser/multitask possono
a volte essere subdole.
EMG

P.S io uso win98.
Puoi usare anche Win NT 5 ma se programmi per i sistemi a 16 bit non lo
sfrutti per nulla (anzi potresti trovare dei problemi di compatibilità).
Ciao, Giuseppe
---------------------------------------------------------------------------
_Guybrush su IRCNet canale #programmazione
ICQ: 42227764
---------------------------------------------------------------------------


L'unica implementazione (molto semplificata) che ho visto io, 
per simulare dei semafori in un sistema a scambio di messaggi era del tipo 
seguente:
Ongi calcolatore della rete ha un "pool di semafori". Su ogni calcolatore
viene fatto andare in esecuzione un "server" che gestisce i semafori.
Se due processi su due calcolatori diversi in rete vogliono bloccarsi
sul semaforo eseguono
Task A:
Invia al una richiesta di wait sul semaforo(x,y)
/* 
 x = calcolatore server del semaforo
 y = identificatore del semaforo locale al server
*/
Esegui una receive e aspetta che il server invii qualcosa
/* la receive bloccante simula la wait sul semaforo */
entra in sezione critica
rilascia il semaforo inviando al server il messaggio opportuno.
ora non siamo piu` in sezione critica
----
Task B:
  come task A
server dei semafori su nodo x:
1- attendi richiesta utilizzo semaforo i-esimo o rilascio semaforo j-simo.
2- se arriva richiesta utilizzo semaforo i-esimo, verifica se nessuno usa
   attualmente tale semaforo
   2a- se si`, accoda la richiesta nella coda delle richieste di
       uso di tale semaforo e vai ad 1
   2b- sblocca il processo richiedente con una opportuna send
3- se arriva rilascio semaforo j, vedi se c'e` qualcuno in attesa di usare
   il semaforo j:
   3a- se no vai a 1
   3b- se si` elimina dalla coda dei richiedenti il processo che si intende
       sbloccare e sblocca tale processo con una opportuna send;
 
Marco Guidi.
 

 Marco Guidi.
Chiedo scusa. Manca la parte di settaggio a busy/free (qualcuno lo usa/nessuno
lo usa) di un semaforo, pero` credo che sia intuitiva
(ad esempio in 2b si potrebbe mettere il semaforo a busy, in 3a a free).
Marco Guidi.