|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Alcune domandine semplici sul C
1) Come faccio a specificare una variabile condivisa tra un processo e tutti i suoi figli futuri? Nel senso che il primo che modifica sta variabile, tale modifica deve essere visibile a tutti.
2) Visto che questo porta problemi di concorrenza: come si usano i semafori in C? C'e' (spero) una funzione che ti garantisce la mutuaesclusione nell'accesso a tale variabile rispetto a tutti i figli? 3) Esiste (qualcuno l'ha creata) una funzione che data una stringa ad ogni occorrenza di una sotto-stringa te la sostituisce con un'altra sotto-stringa? Del tipo: ogni "/" te lo sostituisce con un "?/" grazie in anticipo ciao Cimmo |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Parli di sistemi unix?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#3 |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Si perche' cambia?
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Certo.
Sotto i sistemi unix (in particolare linux) puoi ottenere memoria condivisa tramite shmget (v. pagina man); in sostanza, chiedi un'area di memoria di una certa dimensione, assegnandole una chiave. Qualsiasi altra applicazione che chiede memoria con la stessa chiave ottiene (permessi permettendo) la stessa area. Analogamente puoi ottenere un semaforo con semget (la pagina man indica anche le altre funzioni relative ai semafori); il principio della "chiave" unica è sempre lo stesso. La shm va bene se devi spostare grandi quantità di dati o per accessi frequenti in lettura; altrimenti puoi usare delle valide alternative (come pipe, file mappati in tmpfs, socket ecc.).
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quindi shmget e semget...ok e la terza domanda ne sai qualcosa?
Altra cosa che centra piu' sulla Mandrake 9.0 a) Perche' non c'e' il man di niente (fork, strcmp, tutto manca)? E dire che durante l'installazione ho scelto tutte le categorie...che pacchetto mi manca? b) E' sparito il pacchetto linuxlogo? Se si' lo posso ripescare da qualche parte? grazie ciao Cimmo |
![]() |
![]() |
![]() |
#6 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
Il pacchetto dovrebbe essere man-pages, però è assurdo che non sia installato...vabbè nella mdk 9 ne hanno combinate un pò di tutti i colori Quote:
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quote:
Se faccio man man invece funziona! |
|
![]() |
![]() |
![]() |
#8 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Puoi vedere se sotto /usr/share/man/man2 è presente shmget.2.bz2?
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#9 | ||
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quote:
Codice:
#include <sys/ipc.h> #include <sys/shm.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #define __SHM_MAGIC__ 0x265170a1 #define fail(who) do { perror(who); exit(-1); } while(0) int main() { int id; void *mem; id = shmget(__SHM_MAGIC__, getpagesize(), IPC_CREAT|0660); if(id<0) fail("shmget"); mem = shmat(id, NULL, 0); if(!mem) fail("shmat"); printf("Segmento 0x%08x mappato su %p\n", id, mem); printf("Primo intero: %d\n", (*(int*)mem)++); printf("Nuovo valore: %d\n", *(int*)mem); return 0; } Quote:
|
||
![]() |
![]() |
![]() |
#10 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Ahhh per sbaglio invece di inserire una risposta ho "modificato" il tuo messaggio
![]() La vecchiaia...comunque è il caso di dire che...ti sei risposto da solo ![]() ![]()
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quote:
![]() non fa niente...adesso provero'...e spero di capirci qualcosa! Se ti viene qualcosa anche sui semafori ben venga... ciao Cimmo |
|
![]() |
![]() |
![]() |
#12 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
I semafori sono un pò più complicati dei mutex; guarda man semop/semctl. Prova inoltre questo esempio:
Codice:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #define __SEM_MAGIC__ 0x7688912a #define fail(who) do { perror(who); exit(-1); } while(0) union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; int main() { struct sembuf buf; union semun cmd; int id; id = semget(__SEM_MAGIC__, 1, IPC_CREAT|0660); if(id<0) fail("semget"); fprintf(stderr, "Creato il set di semafori 0x%08x\n", id); /* Inizializza il semaforo, settando semval a 1 */ cmd.val = 1; if(semctl(id, 0, SETVAL, cmd)<0) fail("semctl"); buf.sem_num = 0; buf.sem_flg = SEM_UNDO; /* |IPC_NOWAIT per la forma non bloccante */ fork(); fprintf(stderr, "%d: Provo a bloccare il semaforo...\n", getpid()); buf.sem_op = -1; if(semop(id, &buf, 1)<0) fail("semop"); /* Fallisce con EAGAIN se è specificato IPC_NOWAIT */ fprintf(stderr, "%d: Semaforo bloccato\n", getpid()); sleep(2); /* Aspetto un pò...*/ buf.sem_op = 1; if(semop(id, &buf, 1)<0) fail("semop"); fprintf(stderr, "%d: Semaforo ripristinato\n", getpid()); return 0; }
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#13 |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Alla fine a me serve un semaforo unico, nel senso che mi basterebbe un flag a cui accederci in mutua esclusione...non ho bisogno proprio di un semfaro che per definizione permette n accessi ad una risorsa condivisa (con 0<=n<=MAXRESOURCE)...quindi se esiste in C sotto Unix qualcosa di piu' semplice ancora meglio...illuminami di sapienza!
|
![]() |
![]() |
![]() |
#14 |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Ci sono i pthread_mutex, ma sono utilizzabili solo tra più thread. Non credo che mettendo uno di questi mutex nella memoria condivisa, e accedendoci da diversi processi, l'atomicità delle operazioni di lock sia assicurata.
Con i semafori comunque ottieni lo stesso risultato: pthread_mutex_init <-> cmd.val=1; semctl(id, 0, SETVAL, cmd) pthread_mutex_lock <-> buf.sem_op=-1; semop(id, &buf, 1) pthread_mutex_unlock <-> buf.sem_op=1; semop(id, &buf, 1)
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
![]() |
![]() |
![]() |
#15 |
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Per ora sto provando la shared memory, il problema e' che io ho bisogno di una stringa e lui mi da' un puntatore ad un'area di memoria che puo' essere qualsiasi cosa mi sembra aver capito (la dimensione di questa area pero' mi e' sconosciuta).
Io prima avevo una stringa statica: char str[100]; se volevo scrivere nella 5 posizione facevo: strncpy(&str[4],token,strlen(token)); adesso con un puntatore ad una stringa come cavolo faccio a ricavare l'indirizzo della posizione dalla quale partire a copiare l'altra sottostringa? |
![]() |
![]() |
![]() |
#16 | |
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Devi copiare l'intera stringa nella shm, in quanto un processo non può accedere alla memoria di un altro processo. Tutte le gestioni sulle dimensioni ecc. le devi fare manualmente.
Quote:
E' memoria grezza, come quella allocata con malloc.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
|
![]() |
![]() |
![]() |
#17 | ||
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quote:
Quote:
Thanx |
||
![]() |
![]() |
![]() |
#18 | ||
Senior Member
Iscritto dal: Apr 2000
Città: Roma
Messaggi: 15625
|
Quote:
mem = (char *) shmat(id, NULL, 0); ...e tratti mem come la tua stringa, e ognuno scrive nella posizione che gli compete. Quote:
dim = (dim+getpagesize()-1) & ~(getpagesize()-1); id = shmget(__SHM_MAGIC__, dim, IPC_CREAT|0660); Così "dim" è un multipo di pagina, e contiene almeno la dimensione che hai richiesto.
__________________
0: or %edi, %ecx; adc %eax, (%edx); popf; je 0b-22; pop %ebx; fadds 0x56(%ecx); lds 0x56(%ebx), %esp; mov %al, %al andeqs pc, r1, #147456; blpl 0xff8dd280; ldrgtb r4, [r6, #-472]; addgt r5, r8, r3, ror #12 |
||
![]() |
![]() |
![]() |
#19 | ||
Senior Member
Iscritto dal: Jan 2001
Città: California
Messaggi: 7174
|
Quote:
Quote:
|
||
![]() |
![]() |
![]() |
#20 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
|
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:10.