Unix -?semaphore example
http://docs.linux.cz/programming/c/unix_examples/semab.html



/**//*?semabinit.c?-?initialize?a?semaphore?for?use?by?programs?sema?and?semb?*/

#include?<sys/types.h>
#include?<sys/ipc.h>
#include?<sys/sem.h>
#include?<stdio.h>


/**//*?The?semaphore?key?is?an?arbitrary?long?integer?which?serves?as?an
???external?identifier?by?which?the?semaphore?is?known?to?any?program
???that?wishes?to?use?it.?*/

#define?KEY?(1492)

void?main()


{

???int?id;?/**//*?Number?by?which?the?semaphore?is?known?within?a?program?*/


???/**//*?The?next?thing?is?an?argument?to?the?semctl()?function.?Semctl()?
??????does?various?things?to?the?semaphore?depending?on?which?arguments
??????are?passed.?We?will?use?it?to?make?sure?that?the?value?of?the?
??????semaphore?is?initially?0.?*/


????union?semun?
{
????????int?val;
????????struct?semid_ds?*buf;
????????ushort?*?array;
????}?argument;

???argument.val?=?0;


???/**//*?Create?the?semaphore?with?external?key?KEY?if?it?doesn't?already?
??????exists.?Give?permissions?to?the?world.?*/

???id?=?semget(KEY,?1,?0666?|?IPC_CREAT);


???/**//*?Always?check?system?returns.?*/

???if(id?<?0)

???
{
??????fprintf(stderr,?"Unable?to?obtain?semaphore.\n");
??????exit(0);
???}


???/**//*?What?we?actually?get?is?an?array?of?semaphores.?The?second?
??????argument?to?semget()?was?the?array?dimension?-?in?our?case
??????1.?*/


???/**//*?Set?the?value?of?the?number?0?semaphore?in?semaphore?array
??????#?id?to?the?value?0.?*/

???if(?semctl(id,?0,?SETVAL,?argument)?<?0)

???
{
??????fprintf(?stderr,?"Cannot?set?semaphore?value.\n");
???}
???else

???
{
??????fprintf(stderr,?"Semaphore?%d?initialized.\n",?KEY);
???}
}



/**//*?Semaphore?example?program?a?(sema.c)?*/

/**//*?We?have?two?programs,?sema?and?semb.?Semb?may?be?initiated?at?any?
??time,?but?will?be?forced?to?wait?until?sema?is?executed.?Sema?and
??semb?do?not?have?to?be?executed?by?the?same?user!?*/

#include?<stdio.h>
#include?<sys/types.h>
#include?<sys/ipc.h>
#include?<sys/sem.h>

#define?KEY?(1492)

/**//*?This?is?the?external?name?by?which?the?semaphore?is?known?to?any
???program?that?wishes?to?access?it.?*/

void?main()


{

???int?id;??/**//*?Internal?identifier?of?the?semaphore.?*/
???struct?sembuf?operations[1];

???/**//*?An?"array"?of?one?operation?to?perform?on?the?semaphore.?*/


???int?retval;?/**//*?Return?value?from?semop()?*/


???/**//*?Get?the?index?for?the?semaphore?with?external?name?KEY.?*/
???id?=?semget(KEY,?1,?0666);
???if(id?<?0)

???/**//*?Semaphore?does?not?exist.?*/

???
{
??????fprintf(stderr,?"Program?sema?cannot?find?semaphore,?exiting.\n");
??????exit(0);
???}


???/**//*?Do?a?semaphore?V-operation.?*/
???printf("Program?sema?about?to?do?a?V-operation.?\n");


???/**//*?Set?up?the?sembuf?structure.?*/

???/**//*?Which?semaphore?in?the?semaphore?array?:?*/
????operations[0].sem_num?=?0;

????/**//*?Which?operation??Add?1?to?semaphore?value?:?*/
????operations[0].sem_op?=?1;

????/**//*?Set?the?flag?so?we?will?wait?:?*/???
????operations[0].sem_flg?=?0;


????/**//*?So?do?the?operation!?*/
????retval?=?semop(id,?operations,?1);

????if(retval?==?0)

????
{
???????printf("Successful?V-operation?by?program?sema.\n");
????}
????else

????
{
???????printf("sema:?V-operation?did?not?succeed.\n");
????perror("REASON");
????}
}


/**//*?Think?carefully?about?what?the?V-operation?does.?If?sema?is?executed?
???twice,?then?semb?can?execute?twice.?*/



/**//*?Semaphore?example?program?b?(semb.c)?*/

/**//*?We?have?two?programs,?sema?and?semb.?Semb?may?be?initiated?at?any?
??time,?but?will?be?forced?to?wait?until?sema?is?executed.?Sema?and
??semb?do?not?have?to?be?executed?by?the?same?user!?*/


/**//*?HOW?TO?TEST:
???Execute?semb?&
???The?&?is?important?-?otherwise?you?would?have?have?to?move?to
???a?different?terminal?to?execute?sema.

???Then?execute?sema.
*/

#include?<stdio.h>
#include?<sys/types.h>
#include?<sys/ipc.h>
#include?<sys/sem.h>

#define?KEY?(1492)

/**//*?This?is?the?external?name?by?which?the?semaphore?is?known?to?any
???program?that?wishes?to?access?it.?*/

void?main()


{

???int?id;??/**//*?Internal?identifier?of?the?semaphore.?*/
???struct?sembuf?operations[1];

???/**//*?An?"array"?of?one?operation?to?perform?on?the?semaphore.?*/


???int?retval;?/**//*?Return?value?from?semop()?*/


???/**//*?Get?the?index?for?the?semaphore?with?external?name?KEY.?*/
???id?=?semget(KEY,?1,?0666);
???if(id?<?0)

???/**//*?Semaphore?does?not?exist.?*/

???
{
??????fprintf(stderr,?"Program?semb?cannot?find?semaphore,?exiting.\n");
??????exit(0);
???}


???/**//*?Do?a?semaphore?P-operation.?*/
???printf("Program?semb?about?to?do?a?P-operation.?\n");
???printf("Process?id?is?%d\n",?getpid());


???/**//*?Set?up?the?sembuf?structure.?*/

???/**//*?Which?semaphore?in?the?semaphore?array?:?*/
????operations[0].sem_num?=?0;

????/**//*?Which?operation??Subtract?1?from?semaphore?value?:?*/
????operations[0].sem_op?=?-1;

????/**//*?Set?the?flag?so?we?will?wait?:?*/???
????operations[0].sem_flg?=?0;


????/**//*?So?do?the?operation!?*/
????retval?=?semop(id,?operations,?1);

????if(retval?==?0)

????
{
???????printf("Successful?P-operation?by?program?semb.\n");
???????printf("Process?id?is?%d\n",?getpid());
????}
????else

????
{
???????printf("semb:?P-operation?did?not?succeed.\n");
????}
}


/**//*?Think?carefully?about?what?the?V-operation?does.?If?sema?is?executed?
???twice,?then?semb?can?execute?twice.?*/


先運行semainit,然后后臺運行semb,最后運行sema即可。
http://docs.linux.cz/programming/c/unix_examples/semab.html

































































































































































































































































先運行semainit,然后后臺運行semb,最后運行sema即可。