11.세마포어,메시지,공유 메모리

1.개요

2.세마포어

int semget(key_t key,int num_sems,int sem_flags);

새로운 세마포어를 생성,기존의 세마포어의 키를 구함

key: 세마포어 ID

num_sems: 필요한 세마포어의 수 : 1

sem_flags : IPC_PRIVATE, IPC_CREAT 와 읽기|쓰기|실행

int semop(int sem_id,struct sembuf *sem_ops,size_t num_sem_ops);

세마포어의 값을 변경

sem_id: 세마포어 id

sem_ops :

최소 구조체

struct sembuf{

short sem_num;

short sem_op;

short

ex)sem.c

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include "sem.h"

static int set_semvalue(void);

static void del_semvalue(void);

static int semaphore_p(void);

static int semaphore_v(void);

static int sem_id;

int main(int argc,char *argv[])

{

int i;

int pause_time;

char op_char ='0';

srand((unsigned int)getpid());

sem_id = semget((key_t)1234,1,0666 | IPC_CREAT);

if(argc > 1)

{

if(!set_semvalue())

{

fprintf(stderr,"Failed to initialize semaphore\n");

exit(0);

}

op_char = 'X';

sleep(2);

}

for(i=0;i<10;i++){

if(!semaphore_p())exit(0);

printf("%c",op_char);

fflush(stdout);

pause_time = rand() %3;

sleep(pause_time);

printf("%c",op_char);

fflush(stdout);

if(!semaphore_v())exit(0);

pause_time = rand()%2;

sleep(pause_time);

}

printf("\n%d - finished\n",getpid());

if(argc > 1) {

sleep(10);

del_semvalue();

}

exit(1);

}

static int set_semvalue(void)

{

union semun sem_union;

sem_union.val=1;

if(semctl(sem_id,0,SETVAL,sem_union)==1)return(0);

return(1);

}

static void del_semvalue(void)

{

union semun sem_union;

if(semctl(sem_id,0,IPC_RMID,sem_union)==-1)

fprintf(stderr,"Failed to delete semaphore\n");

}

static int semaphore_p(void)

{

struct sembuf sem_b;

sem_b.sem_num=0;

sem_b.sem_op=-1;

sem_b.sem_flg=SEM_UNDO;

if(semop(sem_id,&sem_b,1) == -1)

{

fprintf(stderr,"semaphore_p failed\n");

return 0;

}

return 1;

}

static int semaphore_v(void)

{

struct sembuf sem_b;

sem_b.sem_num =0;

sem_b.sem_op=1;

sem_b.sem_flg = SEM_UNDO;

if(semop(sem_id,&sem_b,1)==-1)

{

fprintf(stderr,"semaphore_v failed\n");

return 0;

}

return 1;

}

====================================================

sem.h

=====================================================

#ifndef _SEMUN_H

#define _SEMUN_H

union semun{

int val;

struct semid_ds *buf;

unsigned short int *array;

struct seminfo *__buf;

};

#endif

=================================================

3.메시지 큐

ex)msg1.c

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

struct my_msg_st{

long int my_msg_type;

char some_text[BUFSIZ];

}

int main()

{

int running =1;

int msgid;

struct my_msg_st some_data;

long int msg_to_receive =0;

msgid = msgget((key_t)1234,0666 | IPC_CREAT);

if(msgid == -1)

{

fprintf(stderr,"msgget failed with error: %d\n",errno);

exit(0);

}

while(running)

{

if(msgrcv(msgid,(void *)&some_data,BUFSIZ,msg_to_receive,0)==-1)

{

fprintf(stderr,"msgrcv failed with error:%d\n",errno);

exit(0);

}

printf("You wrote:%s",some_data.some_text);

if(strncmp(some_data.some_text,"end",3)==0)

{

running=0;

}

}

if(msgcrl(msgid,IPC_RMID,0)==-1)

{

fprintf(stderr,"msgctl(IPC_RMID)failed\n");

exit(0);

}

exit(1);

}

ex)msg2.c

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#define MAX_TEXT 512

struct my_msg_st

{

long int my_msg_type;

char some_text[MAX_TEXT];

};

int main()

{

int running =1;

struct my_msg_st some_data;

int msgid;

char buffer[BUFSIZ];

msgid=msgget((key_t)1234,0666|IPC_CREAT);

if(msgid==-1)

{

fprintf(stderr,"msgget failed with error:%d\n",errno);

exit(0);

}

while(running)

{

printf("Enter some text:");

fgets(buffer,BUFSIZ,stdin);

some_data.my_msg_type=1;

strcpy(some_data.some_text,buffer);

if(msgsnd(msgid,(void *)&some_data,MAX_TEXT,0)==-1)

{

fprintf(stderr,"msgsnd failed\n");

exit(EXIT_FAILURE);

}

if(strncmp(buffer,"end",3)==0)

{

running=0;

}

}

exit (1);

}

4.공유메모리

ex)

===========================================================

sharem.h

#define TEXT_SZ 2048

struct shared_use_st{

int written_by_you;

char some_text[TEXT_SZ];

};

==========================================================

sharem.c

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include "sharem.h"

int main()

{

int running =1;

void *shared_memory = (void *)0;

struct shared_use_st *shared_stuff;

int shmid;

srand((unsigned int)getpid());

shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666 | IPC_CREAT);

if(shmid == -1)

{

fprintf(stderr,"shmget failed\n");

exit(0);

}

shared_memory = shmat(shmid,(void *)0,0);

if(shared_memory=(void *)-1)

{

fprintf(stderr,"shmat failed\n");

exit(0);

}

printf("Memory attached at %X\n",(int)shared_memory);

shared_stuff = (struct shared_use_st *)shared_memory;

shared_stuff->written_by_you=0;

while(running)

{

if(shared_stuff->written_by_you)

{

printf("You wrote: %s",shared_stuff->some_text);

sleep(rand() % 4);

shared_stuff->written_by_you = 0;

if(strncmp(shared_stuff->some_text,"end",3)==0)

{

running =0;

}

}

}

if(shmdt(shared_memory) == -1)

{

fprintf(stderr,"shmdt failed\n");

exit(0);

}

if(shmctl(shmid,IPC_RMID,0) == -1)

{

fprintf(stderr,"shmctl(IPC_RMID) failed\n");

exit(0);

}

exit(1);

}

=======================================================

sharem2.c

#include <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#include "sharem.h"

int main()

{

int running =1;

void *shared_memory = (void *)0;

struct shared_use_st *shared_stuff;

char buffer[BUFSIZ];

int shmid;

shmid = shmget((key_t)1234,sizeof(struct shared_use_st),0666|IPC_CREAT);

if(shmid == -1)

{

fprintf(stderr,"shmget failed\n");

exit(0);

}

shared_memory = shmat(shmid,(void *)0,0);

if(shared_meory == (void *)-1)

{

fprintf(stderr,"shmat failed\n");

exit(0);

}

printf("Memory attached at %X\n",(int)shared_memory);

shared_stuff=(struct shared_use_st *)shared_memory;

while(running)

{

while(shared_stuff->written_by_you == 1)

{

sleep(1);

printf("Waiting for client ...\n");

}

printf("Enter some text: ");

fgets(buffer,BUFSIZ,stdin);

strncpy(shared_stuff->some_text,buffer,TEXT_SZ);

shared_stuff->written_by_you = 1;

if(sgtrncmp(buffer,"end",3)==0)

{

running =0;

}

}

if(shmdt(shared_memory)==-1)

{

fprintf(stderr,"shmdt failed\n");

exit(0);

}

exit(1);

}

========================================================