|
Posted on 2008-02-21 15:13 ZelluX 閱讀(776) 評論(0) 編輯 收藏 所屬分類: Linux 、 System
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即可。
|