close
total Process 1、Process 2、Process 3
sleep 3 sec 5 sec and 8 sec
use the same
1. semaphore key
2. share memory key
#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <string.h> #include <sys/shm.h> #include <time.h> #include "sem.h" #define SEMKEY 23456 #define SHMKEY 7890 #define SIZEOFSHMSEG 50 int semid; //share memory void *shm_address; int main(){ int shmid,i,loop=3; //struct shmid_ds shmid_struct; //Get share memory shmid = shmget(SHMKEY, SIZEOFSHMSEG,0666 | IPC_CREAT); if (shmid == -1) { printf("main: shmget() failed\n"); return -1; }else{ printf("Process 1 shmid = %d\n",shmid); } //attach share memory shm_address = shmat(shmid, (char *) 0, 0); if ( shm_address==NULL ) { printf("main: shmat() failed\n"); return -1; } //Get semaphore id if (( semid = sem_create(SEMKEY,1)) < 0){ printf("can't open semaphore"); }else{ printf("Process 1 semid = %d\n",semid); } //TODO for(i = 0;i < loop; i++){ usleep(3000000); printf("Process 1 wait[%d] TIME %d\n",i,time(NULL)%100); sem_wait(semid); /* down semaphore */ //semop(semid, &op_lock[0], 2); printf("Process 1 get[%d] share memory TIME %d\n",i,time(NULL)%100); strcpy((char *) shm_address, "hello from Process 1"); printf("Process 1 : \"%s\"\n", (char *) shm_address); usleep(10000000); sem_signal(semid); /* up semaphore */ //semop(semid, &op_unlock[0], 1); printf("Process 1 release[%d] share memory TIME %d\n",i,time(NULL)%100); } //done printf("Process 1 done \n"); //semaphore close sem_close(semid); //remove semaphore id if(semid < 0){ sem_rm(semid); } if(shmctl(shmid,IPC_RMID, (struct shmid_ds *) 0) < 0){ printf("shm IPC_RMID error"); } } |
makefile
all:p1 p2 p3 p1:p1.o cc -o p1 p1.o -lrt p1.o:p1.c cc -c p1.c p2:p2.o cc -o p2 p2.o -lrt p2.o:p2.c cc -c p2.c p3:p3.o cc -o p3 p3.o -lrt p3.o:p3.c cc -c p3.c clean: rm -rf p1 p2 p3 *.o |
semaphore.h
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <errno.h> extern int errno; #define BIGCOUNT 1000 static struct sembuf op_lock[2] = { 2, 0, 0, 2, 1, SEM_UNDO }; static struct sembuf op_endcreate[2] = { 1, -1, SEM_UNDO, 2, -1, SEM_UNDO }; static struct sembuf op_open[1] = { 1, -1, SEM_UNDO }; static struct sembuf op_close[3] = { 2, 0, 0, 2, 1, SEM_UNDO, 1, 1, SEM_UNDO }; static struct sembuf op_unlock[1] = { 2, -1, SEM_UNDO }; static struct sembuf op_op[1] = { 0, 99, SEM_UNDO }; int sem_create(key,initval) key_t key; int initval; { register int id,semval; union semun{ int val; struct semid_ds *buf; ushort *array; }semctl_arg; if( key == IPC_PRIVATE){ return ( -1 ); }else if(key == ( key_t ) -1){ return ( -1 ); } again: if( (id = semget (key, 3, 0666 |IPC_CREAT)) < 0 ){ return ( -1 ); } if(semop(id, &op_lock[0], 2) < 0){ if ( errno == EINVAL){ goto again; printf("cant lock"); } } if( (semval = semctl(id, 1, GETVAL, 0)) < 0){ printf("cant GETVAL"); } if(semval == 0){ semctl_arg.val = initval; if ( semctl(id, 0, SETVAL, semctl_arg) < 0){ printf("can setval[0]"); } semctl_arg.val = BIGCOUNT; if (semctl(id, 1, SETVAL, semctl_arg) < 0){ printf("can setval[1]"); } } if ( semop(id, &op_endcreate[0], 2) < 0){ printf("cant end create"); } return(id); } int sem_open(key) key_t key; { register int id; if ( key == IPC_PRIVATE){ return(-1); } else if( key == (key_t) -1 ){ return (-1); } if((id = semget(key, 3, 0)) < 0){ return (-1); } if( semop(id, &op_open[0], 1) < 0){ printf("cant open"); } return(id); } sem_rm(id) int id; { if ( semctl(id, 0, IPC_RMID, 0) < 0){ printf("cant IPC_RMID"); } } sem_close(id) int id; { register int semval; if(semop(id, &op_close[0], 3) < 0){ printf("cant semop"); } if((semval=semctl(id, 1, GETVAL, 0)) < 0 ){ printf("cant GETVAL"); } if(semval > BIGCOUNT) printf("sem[1] > BIGCOUNT"); else if(semval == BIGCOUNT) sem_rm(id); else if( semop(id, &op_unlock[0], 1) < 0) printf("cant unlock"); } sem_wait(id) int id; { sem_op(id, -1); } sem_signal(id) int id; { sem_op(id, 1); } sem_op(id, value) int id; int value; { if((op_op[0].sem_op = value) == 0){ printf("cant have value == 0"); } if( semop(id, &op_op[0], 1) < 0){ printf("sem_op error"); } } |
全站熱搜