|

楼主 |
发表于 2004-2-10 21:20:23
|
显示全部楼层
自己先贴些源码,为了方便看,在控制终端看不舒服
- /* (c) Louis Granboulan 2000-2003 */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/sem.h>
-
- /*
- * La file est cha頽閑
- * Un maillon contient
- * [ shmid du maillon suivant ; debut, fin, tableau de requetes ]
- * le dernier maillon pointe sur lui-m阭e...
- * Par rapport àl'exercice 1, enfile/defile a comme unique argument variable
- * le shmid du maillon courant.
- * NB: il n'est pas optimal de faire un lock àchaque acc鑣,
- * il vaudrait mieux que le s閙aphore indique le nombre de maillons.
- * Autre diff閞ence : ce n'est plus le p鑢e qui supprime les IPC lorsque
- * le programme finit, mais le fils defileur.
- */
- #define TAILLE 10
- struct requete { int code, valeur; };
- struct maillon { int next; int debut, fin; struct requete tab[TAILLE]; };
- int enfile(void);
- int defile(void);
- void ipcrm(int shmid, int semid, struct maillon *ici);
- void sondied(int sig);
- void ipcclean(int sig);
-
- static struct sembuf op_lock[2] = {
- { 0, 0, 0 },
- { 0, 1, SEM_UNDO },
- };
-
- static struct sembuf op_unlock[1] = {
- { 0, -1, (IPC_NOWAIT | SEM_UNDO) },
- };
-
- int loop = 1;
- /* Les trois suivantes sont globales pour 阾re accessible de "ipcclean" */
- int shmid; /* bloc de m閙oire partag閑 */
- int semid; /* s閙aphore */
- struct maillon *ici; /* maillon courant */
- int main(int argc, char **argv)
- {
- int pidenfile, piddefile;
- semid = semget(IPC_PRIVATE,1,IPC_CREAT|SHM_R|SHM_W);
- if (semid==-1) { perror("semget"); exit(1); }
- shmid = shmget(IPC_PRIVATE, sizeof(struct maillon), IPC_CREAT|SHM_R|SHM_W);
- if (shmid==-1) { perror("shmget"); semctl(semid,0,IPC_RMID,0); exit(1); }
- ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
- [SIZE=4] /* SHM_SHAPE_MMU 是什么意思? */[/size]
- if (ici==0) {
- perror("shmat");
- if (semctl(semid,0,IPC_RMID,0)) { perror("semctl"); }
- if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
- exit(1);
- }
- ici->next = shmid;
- ici->debut = ici->fin = 0;
- pidenfile = fork();
- if (pidenfile<0) { perror("fork"); ipcrm(shmid,semid,ici); exit(1); }
- if (!pidenfile) {
- puts("Je suis le fils qui enfile");
- for ( ; ; ) {
- sleep(3600);
- if (enfile()) { puts("File pleine"); exit(1); }
- }
- exit(0);
- }
- piddefile = fork();
- if (piddefile<0) { perror("fork"); ipcrm(shmid,semid,ici); exit(1); }
- if (!piddefile) {
- puts("Je suis le fils qui defile");
- signal(SIGQUIT,ipcclean);
- signal(SIGTERM,ipcclean);
- signal(SIGINT,ipcclean);
- for ( ; ; ) {
- sleep(3600);
- if (defile()) { puts("File vide"); ipcrm(shmid,semid,ici); exit(1); }
- }
- ipcrm(shmid,semid,ici);
- exit(0);
- }
- signal(SIGCHLD,sondied);
- signal(SIGQUIT,sondied);
- signal(SIGTERM,sondied);
- signal(SIGINT,sondied);
- while (loop) {
- char buffer[80]; fgets(buffer,80,stdin);
- switch (buffer[0]) {
- case '>':
- kill(pidenfile,SIGALRM);
- break;
- case '<':
- kill(piddefile,SIGALRM);
- break;
- default:
- puts("Quit");
- loop = 0;
- }
- }
- kill(pidenfile,SIGTERM);
- kill(piddefile,SIGTERM);
- /* ipcrm(shmid,semid,ici); C'est le fils qui d閒ile qui s'en charge */
- return 0;
- }
- void sondied(int sig) { loop = 0; }
- void ipcclean(int sig) { ipcrm(shmid, semid, ici); }
-
- void ipcrm(int shmid, int semid, struct maillon *ici)
- {
- int next;
- if (semctl(semid,0,IPC_RMID,0)) { perror("semctl"); }
- while (ici && ici->next != shmid) {
- next = ici->next;
- shmdt((void*)ici);
- if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
- shmid = next;
- }
- if (ici) shmdt((void*)ici);
- if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
- }
-
- int enfile()
- {
- int shmnew;
- puts("Enfile");
- if (semop(semid, op_lock, 2) < 0) { perror("semop"); exit(1); }
- ici->fin++;
- if (ici->fin == TAILLE) {
- puts("Cr閍tion d'un maillon");
- shmnew = shmget(IPC_PRIVATE, sizeof(struct maillon), IPC_CREAT|SHM_R|SHM_W);
- if (shmnew==-1) {
- perror("shmget");
- ipcrm(shmid, semid, ici);
- exit(1);
- }
- ici->next = shmnew; shmid = shmnew;
- ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
- if (ici==0) { perror("shmat"); exit(2); }
- ici->next = shmid;
- ici->debut = ici->fin = 0;
- ici->fin++;
- }
- if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
- return 0;
- }
- int defile()
- {
- puts("Defile");
- if (semop(semid, op_lock, 2) < 0) { perror("semop"); exit(1); }
- if (ici->debut == ici->fin) {
- if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
- return 1;
- }
- ici->debut++;
- if (ici->debut == TAILLE) {
- int next = ici->next;
- puts("Destruction d'un maillon");
- shmdt((void*)ici);
- if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
- shmid = next;
- ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
- if (ici==0) { perror("shmat"); exit(2); }
- }
- if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
- return 0;
- }
复制代码
请斑竹们体谅一下。。:rolleyes: 有简单点的例子吗??:confused: :confused: |
|