Ayuda - Semaforos
Publicado por Ivan (1 intervención) el 17/03/2010 09:20:02
Hola, espero que alguien pueda ayudarme.
Es un ejercicio sobre implementación de semaforos binarios en los que 3 procesos usan un semaforo binario para sincronizarse.
Para cambiar el valor del semaforo estoy usando un xchg de manera que la operacion se atomica y mutuamente exclusiva.
Pero estoy teniendo problemas al momento de definir el semaforo en la memoria compartida para que los 3 procesos puedan acceder a el.
Si alguien pudiera orientarme seria de gran ayuda.
El codigo es el siguiente:
-------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#define atomic_xchg(A,B) __asm__ __volatile__( \
" lock xchg %1,%0 ;\n" \
: "=ir" (A) \
: "m" (B), "ir" (A) \
);
#define CICLOS 10
char *pais[3]={"Peru","Bolvia","Colombia"};
struct COLAPROC {
int cola[3];
int ent;
int sal;
} cola_listos, cola_bloqueados;
struct SEMAPHORE {
int cont;
struct COLAPROC colalistos, colabloqueados;
int *semPtr;
} semaforo;
void mete_a_cola(struct COLAPROC *q,int proceso)
{
q->cola[q->ent]=proceso;
q->ent++;
if(q->ent>2)
q->ent=0;
}
int cola_vacia(struct COLAPROC q)
{
if(q.ent==q.sal)
return(1);
else
return(0);
}
int sacar_de_cola(struct COLAPROC *q)
{
int proceso;
proceso=q->cola[q->sal];
q->sal++;
if(q->sal>2)
q->sal=0;
return(proceso);
}
void initSem(int valor)
{
semaforo.cont = valor;
}
void waitB()
{
if (semaforo.cont == 1)
{
int a = 0;
int *aptr = &a;
atomic_xchg(*aptr,semaforo.cont);
printf("Wait: Proceso %i, valor de sem: %i\n", getpid(), semaforo.cont);
} else {
mete_a_cola(&semaforo.colabloqueados, getpid());
printf("Mete a cola bloqueados. Proceso %i\n", getpid());
kill(getpid(),SIGSTOP);
}
}
void signalB()
{
if (cola_vacia(semaforo.colabloqueados))
{
int b = 1;
int *bptr = &b;
atomic_xchg(*bptr,semaforo.cont);
printf("Signal: Proceso %i, valor de sem: %i\n", getpid(), semaforo.cont);
} else {
int pid = sacar_de_cola(&semaforo.colabloqueados);
printf("Saco de cola bloqueados. Proceso %i\n", pid);
mete_a_cola(&semaforo.colalistos, pid);
kill(getpid(),SIGCONT);
printf("Metio a cola listos. Proceso %i\n", pid);
}
}
void proceso(int i)
{
printf("\n%s: %i\n",pais[i], getpid());
int k;
for(k=0;k<10;k++)
{
printf("%i llamo al wait, sem %i\n",getpid(), semaforo.cont);
waitB(); //Llamada wait
printf("Entra %s",pais[i]);
fflush(stdout);
sleep(rand()%3);
printf("- %s Sale\n",pais[i]);
signalB(); //Llamada signal
// Espera aleatoria fuera de la sección crítica
sleep(rand()%3);
}
exit(0); // Termina el proceso
}
int main()
{
int pid;
int status;
int shmid;
int i;
// Declarar memoria compartida
shmid=shmget(0x1234,sizeof(semaforo),0666|IPC_CREAT);
if(shmid==1)
{
perror("Error en la memoria compartida\n");
exit(1);
}
semaforo=shmat(shmid,NULL,0);
if(sem==NULL)
{
perror("Error en el shmat\n");
exit(2);
}
initSem(1);
printf("Se inicia sem: %i\n", semaforo->cont);
srand(getpid());
for(i=0;i<3;i++)
{
// Crea un nuevo proceso hijo que ejecuta la función proceso()
pid=fork();
if(pid==0)
{
printf("Creó proceso %i", i);
proceso(i);
}
}
for(i=0;i<3;i++)
{
pid = wait(&status);
}
printf("hola\n");
// Eliminar la memoria compartida
shmdt(sem);
}
----------------------------------------------------------------------------------
El resultado deberia ser algo como esto:
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Gracias.
Es un ejercicio sobre implementación de semaforos binarios en los que 3 procesos usan un semaforo binario para sincronizarse.
Para cambiar el valor del semaforo estoy usando un xchg de manera que la operacion se atomica y mutuamente exclusiva.
Pero estoy teniendo problemas al momento de definir el semaforo en la memoria compartida para que los 3 procesos puedan acceder a el.
Si alguien pudiera orientarme seria de gran ayuda.
El codigo es el siguiente:
-------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#define atomic_xchg(A,B) __asm__ __volatile__( \
" lock xchg %1,%0 ;\n" \
: "=ir" (A) \
: "m" (B), "ir" (A) \
);
#define CICLOS 10
char *pais[3]={"Peru","Bolvia","Colombia"};
struct COLAPROC {
int cola[3];
int ent;
int sal;
} cola_listos, cola_bloqueados;
struct SEMAPHORE {
int cont;
struct COLAPROC colalistos, colabloqueados;
int *semPtr;
} semaforo;
void mete_a_cola(struct COLAPROC *q,int proceso)
{
q->cola[q->ent]=proceso;
q->ent++;
if(q->ent>2)
q->ent=0;
}
int cola_vacia(struct COLAPROC q)
{
if(q.ent==q.sal)
return(1);
else
return(0);
}
int sacar_de_cola(struct COLAPROC *q)
{
int proceso;
proceso=q->cola[q->sal];
q->sal++;
if(q->sal>2)
q->sal=0;
return(proceso);
}
void initSem(int valor)
{
semaforo.cont = valor;
}
void waitB()
{
if (semaforo.cont == 1)
{
int a = 0;
int *aptr = &a;
atomic_xchg(*aptr,semaforo.cont);
printf("Wait: Proceso %i, valor de sem: %i\n", getpid(), semaforo.cont);
} else {
mete_a_cola(&semaforo.colabloqueados, getpid());
printf("Mete a cola bloqueados. Proceso %i\n", getpid());
kill(getpid(),SIGSTOP);
}
}
void signalB()
{
if (cola_vacia(semaforo.colabloqueados))
{
int b = 1;
int *bptr = &b;
atomic_xchg(*bptr,semaforo.cont);
printf("Signal: Proceso %i, valor de sem: %i\n", getpid(), semaforo.cont);
} else {
int pid = sacar_de_cola(&semaforo.colabloqueados);
printf("Saco de cola bloqueados. Proceso %i\n", pid);
mete_a_cola(&semaforo.colalistos, pid);
kill(getpid(),SIGCONT);
printf("Metio a cola listos. Proceso %i\n", pid);
}
}
void proceso(int i)
{
printf("\n%s: %i\n",pais[i], getpid());
int k;
for(k=0;k<10;k++)
{
printf("%i llamo al wait, sem %i\n",getpid(), semaforo.cont);
waitB(); //Llamada wait
printf("Entra %s",pais[i]);
fflush(stdout);
sleep(rand()%3);
printf("- %s Sale\n",pais[i]);
signalB(); //Llamada signal
// Espera aleatoria fuera de la sección crítica
sleep(rand()%3);
}
exit(0); // Termina el proceso
}
int main()
{
int pid;
int status;
int shmid;
int i;
// Declarar memoria compartida
shmid=shmget(0x1234,sizeof(semaforo),0666|IPC_CREAT);
if(shmid==1)
{
perror("Error en la memoria compartida\n");
exit(1);
}
semaforo=shmat(shmid,NULL,0);
if(sem==NULL)
{
perror("Error en el shmat\n");
exit(2);
}
initSem(1);
printf("Se inicia sem: %i\n", semaforo->cont);
srand(getpid());
for(i=0;i<3;i++)
{
// Crea un nuevo proceso hijo que ejecuta la función proceso()
pid=fork();
if(pid==0)
{
printf("Creó proceso %i", i);
proceso(i);
}
}
for(i=0;i<3;i++)
{
pid = wait(&status);
}
printf("hola\n");
// Eliminar la memoria compartida
shmdt(sem);
}
----------------------------------------------------------------------------------
El resultado deberia ser algo como esto:
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Peru- Peru Sale
Entra Bolvia- Bolvia Sale
Entra Colombia- Colombia Sale
Entra Peru- Peru Sale
Gracias.
Valora esta pregunta


0