天天看點

semget, semop and semctl函數小記

semget function

    the prototype of semget is

        int semget(key_t key, intnsems,int semflg);

    we use semget() toget a semaphore set id. after we call semget() successfully, it returns a non-negative

integer, often calledsem_id, which other semaphore functions use to access the semaphore set. on error, it returns -1.

    note that the phrase is "semaphore set". that means it is an array of semaphores, and the 2nd argumentnsems

decides how many elements the array owns, though almost we just need 1.

    i was a little confused by the 1st argument key at first, because i don't know how it works.

    then i looked up the linux manual page.

    here comes the partial description of semget():

        the semget() system call returns the semaphore set identifier associated with the

argument key. a new set of nsems semaphores is created if key has the value ipc_private or if no existing semaphore set is associated with key and ipc_creat is specified in semflg.

    and then i know the parameter key is an integer associated to the special semaphore. when the system plans to create a new semaphore,

it checks the key first to see if another one connected to the key has existed, if so, the system fails with errno.

    on another occasion, if we set the key to ipc_private, then we can obtain a private semaphore, which means the semaphore can only

be accessed by one particular process or thread, so we know it is useless. always we should provide a unique and non-zero integer for key.

semopfunction

    the prototype of semop is

        int semop(int semid, struct

sembuf *sops, unsigned nsops);

    we could easily know that this function is used toperform some operation on

semaphores from the name of it.

    but how it actually works?

    as is refered to above, the function semget() returns an id pointing to an array of semaphores,

and the argument nsems in semget() indicates how many they are. so when we decide to make some change on semaphores, we should know where the semaphores are first, so we get thesemid

pointing to the array. and then we should know how many operations will be performed, that is why the 3rd parameternsops

exists.

    finally,how we make changes on the semaphores? we usestruct sembuf.

    the structure comes below:

        unsigned

short sem_num; /*semaphore number */

        short sem_op; /* semaphore

operation */

        short sem_flg; /* operation

flags */

    sem_num indicates which semaphore in the set would be operate, usually it is set to 0.

    sem_op holds the value by which the semaphore would change. generally, +1 is used for p operation and

-1 for v to say that the critical section is available now.

    it is good to set thesem_flg to

sem_undo, so that when the process terminates, the operation could be undone automatically.

    on the whole, we use semid to point to the destination set, sops to indicates where the operation array is, then the system performs

nsops operation to make changes on the semaphores in the sops array order.

    for instance, we call semop(sem_id, buf, 3). the 2nd argument buf is a pointer pointing to an array of struct sembuf

owning at least 3 elements. the system catch the 3rd argument 3 to know 3 operations will be performed with the information given by the2nd argument buf. we said that these operations will be performed in the sops array order, so the

system would just make changes on semaphores whose id is among buf[0].sem_num, buf[1].sem_num and buf[2].sem_num, and of course, each operation will be done according to the buf[i].sem_op, in which i is among 0, 1, 2.

    note that the operation is done atomically and automatically.

semctl function

    the prototype of the semctl is:

        int semctl(int semid, intsemnum,

int cmd, ...);

    this functionperforms an direct operation on the semnum-th semaphore in the semaphore set whose id is

semid with the argument cmd.

    there are many kinds of cmd, which affects the 4th argument's existence.usually we use two command, setval and ipc_rmid.

    for command setval we need a 4th argument to indicate the value to set to the semnum-th semaphore in the set owning

the id semid.

    the4th argument structure follows:

         union semun {

               int val; /* value for setval */

               struct semid_ds *buf; /* buffer for ipc_stat, ipc_set */

               unsigned short *array; /* array for getall, setall */

               struct seminfo *__buf; /* buffer for ipc_info

                                        (linux-specific)*/

          };

     and for command ipc_rmid, we aims at removing the semaphore set whose id is semid, and awakening the processes blocked for the set. under this circumstance, the

argument semnum is ignored.

jasonlee

2009-11-14p.m

————————————————————————————————————————

[部落格整理補充] 這篇文章是在校期間用ubuntu時,中文輸入法不好使,就用英文寫了。現在回頭看,發現還是讀過過去的。

semget, semop and semctl函數小記

時光飛逝啊,一晃都兩年多了。 2012-07-30晚。

繼續閱讀