/*
SC.H QNX CLIENT/SERVER HEADER FILE. POSIX VERSION
*/
/* Ñòðóêòóðà, îïðåäåëÿþùàÿ äàííûå. Ñòðóêòóðà
çàïðîñà ñîâïàäàåò ñî ñòðóêòóðîé îòâåòà íà çàïðîñ*/
typedef struct
{ int
data;
int cmd;
} SHMdata;
/*ïóòåâîå èìÿ ðàçäåëÿåìîé
ïàìÿòè; àíàëîãè÷íî îïðåäåëåíèþ èìåíè ôàéëà
*/
char *SHMname = "DATAMEMORY";
typedef struct
{ sem_t
access; // ñåìàôîð äîñòóïà
sem_t answer; // ñåìàôîð îòâåòà
sem_t query; //
ñåìàôîð çàïðîñà
} SEMAPHORE;
/*ñåìàôîð äîëæåí áûòü äîñòóïåí: îáúÿâëÿåìûå
ñåìàôîðû äîëæíû íàõîäèòñÿ â ðàçäåëÿåìîé ïàìÿòè*/
char *SEMmemory = "SEMMEMORY";
void serror(char *msg)
{ printf("\nerror
[%d]: %s:%s\n",getpid(),msg, strerror(errno));
exit(1);
}
/*
QNX SERVER. POSIX VERSION
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include
<sys/mman.h> /*îïèñàíèå ôóíêöèé äëÿ ðàáîòû ñ ðàçäåëÿåìîé ïàìÿòüþ*/
#include
<semaphore.h> /*îïèñàíèå ôóíêöèé ñåìàôîðîâ*/
#include "sc.h"
SEMAPHORE *SEM;
SHMdata *addr;
void main(int argc, char *argv[])
{ int fd,
nval;
int counter;
/* Ñîçäàåì ðàçäåëÿåìóþ
ïàìÿòü */
fd = shm_open(SHMname, O_RDWR | O_CREAT | O_EXCL, 0777);
if(fd<0)
{ printf("\ncan't
open shmem (%s). Try to close it\n",strerror(errno));
shm_unlink(SHMname);
fd
= shm_open(SHMname, O_RDWR | O_CREAT | O_EXCL, 0777);
if(fd<0)
puts("can't open shmem");
}
/* Óñòàíàâëèâàåì ðàçìåð
îáëàñòè */
if(ltrunc(fd,sizeof(SHMdata),SEEK_SET)==-1)
serror("set shm size error");
addr
=mmap(0,sizeof(SHMdata),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(addr == (void *)-1) serror("mmap failed");
close(fd);
printf("\nMap address = %6.6X\n",addr);
/* Îòêðûòü ðàçäåëÿåìóþ
ïàìÿòü äëÿ SEMAPHORE */
/* ñåìàôîðû äîñòóïíû äðóãèì - íå ðîäñòâåííûì
- ïðîöåññàì òîëüêî â
ðàçäåëÿåìîé ïàìÿòè. Íóæíî îòêðûòü ïàìÿòü äëÿ
ðàçäåëÿåìîãî ñåìàôîðà */
fd = shm_open(SEMmemory, O_RDWR | O_CREAT | O_EXCL,
0777);
if(fd<0)
{ printf("\ncan't
open shmem for SEMAPHORE (%s). Try to close it\n",
strerror(errno));
shm_unlink(SEMmemory);
fd
= shm_open(SEMmemory,O_RDWR|O_CREAT|O_EXCL,0777);
if(fd<0)
puts("can't open shmem for SEMAPHORE");
}
/* Óñòàíàâëèâàåì ðàçìåð
îáëàñòè */
if(ltrunc(fd,sizeof(SEMAPHORE),SEEK_SET)== -1)
serror("set
shm size error for SEMAPHORE");
SEM = mmap(0,sizeof(sem_t),
PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
if(SEM == (void *)-1) serror("mmap for SEMAPHORE
failed");
close(fd);
printf("\nMap address for SEMAPHORE =
%6.6X\n",SEM);
/* Îòêðûâàåì ñåìàôîðû */
if(sem_init(&SEM->access,1,1)<0)
serror("sem_init/access");
if(sem_init(&SEM->answer,1,0)<0)
serror("sem_init/answer");
if(sem_init(&SEM->query,1,0)<0)
serror("sem_init/query");
printf("\nSERVER SEMAPHORES\n");
printf("\taccess: semid=(%d) value=(%d)\n",
SEM->access.semid,SEM->access.value);
printf("\tanswer: semid=(%d) value=(%d)\n",
SEM->answer.semid,SEM->answer.value);
printf("\tquery:
semid=(%d) value=(%d)\n", SEM->query.semid,SEM->query.value);
/* Îñíîâíîé öèêë
ïðîãðàììû-ñåðâåðà */
counter=0;
addr->cmd = 1;
while(1)
{ if(sem_wait(&SEM->query)<0)
serror("sem_wait/query");
if(addr->cmd==0)
break;
nval =
(addr->data)+100;
(addr->data)
= nval;
counter++;
if(sem_post(&SEM->answer)<0)
serror("sem_post/answer");
if(sem_post(&SEM->access)<0)
serror("sem_post/access");
}
/* Óäàëÿåì ñåìàôîðû */
if(sem_destroy(&SEM->access)<0)
serror("sem_destroy/access");
if(sem_destroy(&SEM->answer)<0)
serror("sem_destroy/answer");
if(sem_destroy(&SEM->query)<0)
serror("sem_destroy/query");
shm_unlink(SEMmemory);
shm_unlink(SHMname);
printf("\n\nSERVER TERMINATED\nTotal queries =
%d\n",counter);
}
/*
QNX CLIENT. POSIX VERSION
*/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <semaphore.h>
#include "sc.h"
SEMAPHORE *SEM;
SHMdata *addr;
void main(int argc, char *argv[])
{ int fd;
int counter;
int nval;
/* Îòêðûâàåì
ðàçäåëÿåìóþ ïàìÿòü */
fd = shm_open(SHMname, O_RDWR, 0777);
if(fd<0) serror("can't open shmem");
addr = mmap(0, sizeof(SHMdata) , PROT_READ | PROT_WRITE,
MAP_SHARED, fd,0);
if(addr == (void *)-1) serror("mmap failed");
close(fd);
printf("\nclient[%d]: Map address =
%6.6X\n",getpid(),addr);
/* Îòêðûòü ðàçäåëÿåìóþ
ïàìÿòü äëÿ SEMAPHORE */
fd = shm_open(SEMmemory, O_RDWR, 0777);
if(fd<0) serror("can't open shmem for
SEMAPHORE");
SEM=mmap(0,sizeof(SEMAPHORE),PROT_READ|PROT_WRITE,
MAP_SHARED,fd,0);
if(SEM == (void *)-1) serror("mmap failed");
close(fd);
printf("\nCLIENT [%d]: Map address for SEMAPHORE =
%6.6X\n", getpid(),SEM);
printf("\nCLIENT [%d] SEMAPHORES\n",getpid());
printf("\taccess: semid=(%d) value=(%d)\n",
SEM->access.semid,SEM->access.value);
printf("\tanswer: semid=(%d) value=(%d)\n",
SEM->answer.semid,SEM->answer.value);
printf("\tquery: semid=(%d) value=(%d)\n",
SEM->query.semid,SEM->query.value);
/* Îñíîâíîé öèêë
ïðîãðàììû-ñåðâåðà */
for(counter=1;counter<argc;counter++)
{ sleep(1); // çàäåðæêà (äëÿ ÷èñòîòû
ýêñïåðèìåíòà)
/*
æäåì äîñòóïà */
if(sem_wait(&SEM->access)<0)
serror("sem_wait/access");
nval
= atoi(argv[counter]);
printf("\n\t-client
[%d]: count me %d",getpid(),nval);
addr->data
= nval;
addr->cmd
= nval;
sem_post(&SEM->query);
/*
æäåì îòâåòà */
if(sem_wait(&SEM->answer)<0)
serror("sem_wait/access");
printf("\n\t-client
[%d]: got answer: %d", getpid(),addr->data);
}
printf("\n**
client [%d]: terminated\n",getpid());
}
Ïðèìåð çàïóñêà ñåðâåðà è
êëèåíòîâ:
server &
client
3 5 6 &
client
8 3 9 &
client
5 1 0 &
/* LINUX CALC SERVER/CLIENT HEADER */
#ifndef _SC_H_
#define _SC_H_
#include
<sys/ipc.h>
#include
<sys/shm.h>
#include
<sys/sem.h>
/* shared memory key */
#define SHMid 123
typedef struct
{ int data;
char string[512];
int count;
int cmd;
} SHMdata;
#define SEMid 321
/* semaphores */
#define access 0
#define answer 1
#define query 2
/* semaphore operator */
struct sembuf sop;
int sem_wait(int sid, int
snum)
/* function P */
{ sop.sem_num = snum; /* semaphore number */
sop.sem_op = -1;
return semop(sid,&sop,1);
}
int sem_post(int sid, int
snum)
/* function V */
{ sop.sem_num = snum; /* semaphore number */
sop.sem_op = 1;
return semop(sid,&sop,1);
}
#endif
/* LINUX CALC SERVER */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include
<sys/mman.h>
#include
<sys/types.h>
#include
<sys/ipc.h>
#include
<sys/shm.h>
#include "sc.h"
SHMdata *addr;
void serror(char *msg)
{ printf("\nserver error [%d]:
%s:%s\n",getpid(),msg,strerror(errno));
exit(1);
}
void main(int argc, char
*argv[])
{ int nval;
int sid;
int shmid;
short initarray[3] = {1,0,0}; /* access,answer,query
*/
/* Open sh memory */
shmid = shmget(SHMid,sizeof(SHMdata), 0777 |
IPC_CREAT);
addr = (SHMdata *)shmat(shmid,0,0);
printf("\nserver: map address =
%6.6X\n",addr);
/* create and init semaphores */
sid = semget(SEMid,3,0777 | IPC_CREAT);
/* init semaphores*/
semctl(sid,3,SETALL,initarray); /*
access=1,answer=0,query=0 */
// sem_init(&SEM->access,1,1)
// sem_init(&SEM->answer,1,0)
// sem_init(&SEM->query,1,0)
/* main program loop */
addr->cmd = 1;
while(1)
{ if(sem_wait(sid,query)<0) serror("sem_wait/query");
if(addr->cmd==0) break;
nval = (addr->data)+100;
(addr->data) = nval;
if(sem_post(sid,answer)<0) serror("sem_post/answer");
if(sem_post(sid,access)<0) serror("sem_post/access");
}
/* delete semaphore */
semctl(sid,3,IPC_RMID,0);
/* delete shared memory*/
shmctl(shmid,IPC_RMID,0);
printf("\n\nserver terminated\n");
}
/* LINUX CALC CLIENT */
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/mman.h>
#include
<sys/types.h>
#include
<sys/ipc.h>
#include
<sys/shm.h>
#include "sc.h"
SHMdata *addr;
void serror(char *msg)
{ printf("\nclient error [%d]:
%s:%s\n",getpid(),msg,strerror(errno));
exit(1);
}
void main(int argc, char
*argv[])
{ int shmid;
int semid;
int counter, nval;
/* Open sh memory */
shmid = shmget(SHMid, sizeof(SHMdata), 0777);
addr = (SHMdata *)shmat(shmid,0,0);
printf("\nclient [%d]: map address =
%6.6X\n",getpid(),addr);
/* open semaphores */
semid = semget(SEMid,0,0);
/* main program loop */
for(counter=1;counter<argc;counter++)
{ sleep(1);
/* wait for access */
if(sem_wait(semid,access)<0) serror("sem_wait/access");
nval = atoi(argv[counter]);
printf("\n\tclient [%d]: -Count
me %d",getpid(),nval);
addr->data=nval;
addr->cmd = nval;
sem_post(semid,query);
/* wait for answer */
if(sem_wait(semid,answer)<0) serror("sem_wait/access");
printf("\n\tclient [%d]: -Got
answer %d",getpid(),addr->data);
}
printf("\n** client
[%d] terminated\n",getpid());
}