基本函数: //semaphore function
int create_sem(key_t key, int members) { int cntr; union semun semopts; int semid; jprintf("Attempting to create new semaphore set with %d members\n",members); if((semid = semget(key, members, IPC_CREAT|IPC_EXCL|0666)) == -1) { jprintf("Semaphore set already exists!\n"); return -1; } semopts.val = 1; //最大的资源个数,这里就是互斥锁的功能,所以就是 0 | 1 , 二值信号量
/* Initialize all members (could be done with SETALL) */ for(cntr=0; cntr<members; cntr++) semctl(semid, cntr, SETVAL, semopts); //cntr 这里是信号量集里面得信号灯的索引!
return semid; }
int open_sem(key_t key) { int semid; /* Open the semaphore set - do not create! */ if((semid = semget(key, 0, 0666)) == -1) { jprintf("Semaphore set does not exist!\n"); } return semid; }
int lock_sem(int semid, int member) { struct sembuf sem_lock={ member, -1, SEM_UNDO};//-1 :decrease, 1:increase
int semval; jprintf(" ----------------------------------in begin to get semaphore ---------------------------------\n"); semval = semctl(semid, member, GETVAL, 0); jprintf("current value = %d\n",semval); if( semop(semid, &sem_lock, 1) == -1) //it will be blocked until get the access
{ fprintf(stderr, "Lock failed\n"); return -1; } else jprintf("Semaphore resources decremented by one (locked)\n"); semval = semctl(semid, member, GETVAL, 0); jprintf("semval for member %d is %d\n", member, semval); jprintf("-------------------------------------Has get semaphore -------------------------------------\n"); return 0; }
int unlock_sem(int semid, int member) { struct sembuf sem_unlock={ member, 1, SEM_UNDO }; int semval; /* Is the semaphore set locked? */ semval = semctl(semid, member, GETVAL, 0); jprintf("\n-----------------------in unlock_sem ----------------------------\n"); jprintf("current semaphore value = %d\n",semval); if(semval > 0) { jprintf("it has been unlocked , I did nothing \n"); return 0; } /* Attempt to lock the semaphore set */ if((semop(semid, &sem_unlock, 1)) == -1) { fprintf(stderr, "Unlock failed\n"); return -1; } else printf("Semaphore resources incremented by one (unlocked)\n"); semval = semctl(semid, member, GETVAL, 0); jprintf("semval for member %d is %d\n", member, semval); jprintf("----------------------------unlock sem --------------------------------\n"); return 0; }
|
例子: /** * query those files which are downloading from share memory to get status info * generally , conf_name is /etc/shm.conf for CGI , should have a version for Socket query int QueryShmForClient(DownloadFileInfoList *DList ,const char *conf_name , const char *client_ip); **/ int QueryShm(DownloadFileInfoList *DList, const char *conf_name) //etc/shm.conf
{ char ptr[128]; FILE *fp = NULL; int fd = 0; char *seg = NULL; key_t key; int shmid; //share memory ID
int semid; //semaphore ID
void *segptr = NULL; int downloading_num = 0; int rc = 0; assert(DList); fp = fopen(conf_name,"rt"); if(!fp) { fatal_err("can't open /etc/shm.conf\n"); LogMesg("can't open /etc/shm.conf , maybe /etc/shm.conf doesn't exist any longer \n"); return SERVER_CANNOT_OPEN_SHM_CONF; } assert(fp); fd = fileno(fp); //lockf(fd,F_LOCK,0);
readw_lock(fd,0,SEEK_SET,0); while(fgets(ptr,sizeof(ptr),fp)) { //get a line
DownloadFileInfo *doingJob_entry = (DownloadFileInfo *)malloc(sizeof(DownloadFileInfo)); //assert(doingJob_entry);
if(!doingJob_entry) { fatal_err("can't malloc DownloadFileInfo struct entry \n"); continue; } jprintf("ptr = %s\n",ptr); seg = strrchr(ptr,':'); if(seg == NULL) { jprintf("can't find \':\' in %s , maybe this line in shm.conf has problem ,please check %s\n",ptr,SHM_CONF); continue; } *seg = '\0'; //now ptr should be fullpathname ,ie, /harddisk/hd~2/data/public/bob/linux-2.4.21.tar.gz
//---------------------------Start reading share memory----------------------------
key = ftok(ptr,0); // ----------------------------------semaphore mutex lock -------------------------------------
#if 0 semid = open_sem(key); //get a ID of a existing semaphore set
if(semid < 0) { fatal_err("get semaphore failure , job name (%s) \n",ptr); continue; } rc = lock_sem(semid ,0); if(rc < 0) { fatal_err("Sorry ,lock failed for(%s) \n",ptr); continue; } jprintf("haha , you have get the mutex lock , you can read the share memory segment !\n"); #endif // ----------------------------------------------------------------------------------------------
if((shmid = shmget(key, SEGSIZE, 0444)) == -1) { fatal_err("can't get share memory ,key(%s) \n",key); LogMesg("the key (%s) of file (%s) 's share memory looks that has problem(shmget error ) ,please check \n",key,SHM_CONF); //return SERVER_SHMGET_FAIL;
continue; } else { jprintf("shmid = %d\n",shmid); jprintf("has attached memory segment\n"); } /* Attach (map) the shared memory segment into the current process */ if((segptr = shmat(shmid, 0, 0)) == NULL) { fatal_err("can't shmat share memory ,key (%s) \n",key); LogMesg("the key (%s) of file (%s) 's share memory looks that has problem(shmat error ) ,please check \n",key,SHM_CONF); //return SERVER_SHMAT_ERROR;
continue; } //memcpy(doingJob_entry,(DownloadFileInfo *)segptr,sizeof(DownloadFileInfo)); ////fill the doingJob_entry , if problem ,single assign ,bob 2005-12-29 10:51
*doingJob_entry = *((DownloadFileInfo *)segptr); shmdt(segptr); //unlock the mutex lock
#if 0 unlock_sem(semid,0); #endif AddDownloadFileInfoList(DList,doingJob_entry); //add the node into the List
downloading_num++; } //endof while(fgets(ptr,sizeof(ptr),fp))
//lockf(fd,F_ULOCK,0);
un_lock(fd,0,SEEK_SET,0); fclose(fp); if(downloading_num==0) { jprintf("there is no job downloading in share memory \n"); } else { jprintf("there is %d files downloading \n",downloading_num); } return 0; }
|
|
|