基本函数:
例子:
//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;
}