信号量的通信

来源:互联网 发布:水知道答案知乎 编辑:程序博客网 时间:2024/06/16 22:33

《Makefile》

##############################
# farsight's Makefile
# Write by StephenYee(StephenYee@farsight.com.cn)
#
##############################

#INSTALLROOT=$(PWD)


#CROSS_COMPILE = arm-linux-gnu-

CC = $(CROSS_COMPILE)gcc

ifdef CROSS_COMPILE
TARGET_FS_PATH = /opt/filesystem
endif

BIN_PATH =$(TARGET_FS_PATH)/root/long_term/ipc

INSTALL=install

#WARNINGS = -Wall \
#           -Wundef -Wpointer-arith -Wbad-function-cast \
#           -Wcast-align -Wwrite-strings -Wstrict-prototypes \
#           -Wmissing-prototypes -Wmissing-declarations \
#           -Wnested-externs -Winline -Wcast-qual -W \
#           -Wno-unused
#           -Wunused

CFLAGS= -O2 -DLINUX $(WARNINGS)

#LIBS= -lpthread

BINARY1 = producer
BINARY2 = customer
OBJS1 = producer.o sem_com.o
OBJS2 = customer.o sem_com.o
HEADERS = shm_com.h sem_com.h


all:${BINARY1} ${BINARY2}
${BINARY1} : ${OBJS1}
 ${CC} ${CFLAGS} ${LDFLAGS} -o $@ $^
${BINARY2} : ${OBJS2}
 ${CC} ${CFLAGS} ${LDFLAGS} -o $@ $^

${OBJS1} : ${HEADERS}
${OBJS2} : ${HEADERS}

%.o : %.c 
 $(CC) $(CFLAGS) -c -o $@ $<

.PHONY: install uninstall clean dis


install: $(BINARY)
 $(INSTALL) -s -m 755 -g root -o root $(BINARY) $(BIN_PATH)

uninstall:
ifdef CROSS_COMPILE
 cd  $(BIN_PATH) && rm -f  ${BINARY1}  ${BINARY2}
endif

clean : uninstall
 - rm -f core *.gz
 - rm -f ${OBJS1} ${BINARY1}
 - rm -f ${OBJS2} ${BINARY2}

dist: clean
 tar czf farsight_ipc_customer_product_demo1.0.tar.gz *.c *.h Makefile

 ***************************************************************************

《头文件》


/* sem_com.h */

#ifndef  SEM_COM_H
#define  SEM_COM_H

#include <sys/ipc.h>
#include <sys/sem.h>

union semun
{
 int val;
 struct semid_ds *buf;
 unsigned short *array;
};

int init_sem (int, int);
int del_sem (int);
int sem_p (int);
int sem_v (int);

#endif       /* SEM_COM_H */

-----------------------------------------

《头文件二》


/* shm_com.h */

#ifndef  SHM_COM_H
#define  SHM_COM_H

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#define SHM_BUFF_SZ 2048

struct shm_buff
{
 int pid;
 char buffer[SHM_BUFF_SZ];
};

#endif       /* SHM_COM_H */

*******************************************************

《另一个pv编程》


/* sem_com.c */

#include "sem_com.h"

int init_sem (int sem_id, int init_value)
{
 union semun sem_union;
 sem_union.val = init_value;
 if (semctl (sem_id, 0, SETVAL, sem_union) == -1) {
  perror ("Initialize semaphore");
  return -1;
 }
 return 0;
}

int del_sem (int sem_id)
{
 union semun sem_union;
 if (semctl (sem_id, 0, IPC_RMID, sem_union) == -1) {
  perror ("Delete semaphore");
  return -1;
 }
}

int sem_p (int sem_id)
{
 struct sembuf sem_b;
 sem_b.sem_num = 0;   /*id */
 sem_b.sem_op = -1;   /* P operation */
 sem_b.sem_flg = SEM_UNDO;

 if (semop (sem_id, &sem_b, 1) == -1) { /*1:first struct */
  perror ("P operation");
  return -1;
 }
 return 0;
}

int sem_v (int sem_id)
{
 struct sembuf sem_b;

 sem_b.sem_num = 0;   /* id */
 sem_b.sem_op = 1;   /* V operation */
 sem_b.sem_flg = SEM_UNDO; /* It's tracks be follow, to automatical free for it */

 if (semop (sem_id, &sem_b, 1) == -1) {
  perror ("V operation");
  return -1;
 }
 return 0;
}

***********************************

《write操作》


/* producer.c */

#include "shm_com.h"
#include "sem_com.h"
#include <signal.h>

int ignore_signal (void)
{
 signal (SIGINT, SIG_IGN);
 signal (SIGSTOP, SIG_IGN);
 signal (SIGQUIT, SIG_IGN);
 return 0;
}

int main ()
{
 void *shared_memory = NULL;
 struct shm_buff *shm_buff_inst;
 char buffer[BUFSIZ];
 int shmid, semid;

 ignore_signal ();   /* 防止程序非正常退出 */
 semid = semget (ftok (".", 'a'), 1, 0666 | IPC_CREAT); /* 创建一个信号量 */
 init_sem (semid, 1);  /* 初始值为1 */

 /* 创建共享内存 */
 shmid = shmget (ftok (".", 'b'), sizeof (struct shm_buff), 0666 | IPC_CREAT);
 if (shmid == -1) {
  perror ("shmget failed");
  del_sem (semid);
  exit (1);
 }

 /* 将共享内存地址映射到当前进程地址空间 */
 shared_memory = shmat (shmid, (void *) 0, 0);
 if (shared_memory == (void *) -1) {
  perror ("shmat");
  del_sem (semid);
  exit (1);
 }
 printf ("Memory attached at %X\n", (int) shared_memory);
 /* 获得共享内存的映射地址 */
 shm_buff_inst = (struct shm_buff *) shared_memory;

 do {
  sem_p (semid);
  printf ("Enter some text to the shared memory(enter 'quit' to exit):");

  /* 向共享内存写入数据 */
  if (fgets (shm_buff_inst->buffer, SHM_BUFF_SZ, stdin) == NULL) {
   perror ("fgets");
   sem_v (semid);
   break;
  }
  shm_buff_inst->pid = getpid ();
  sem_v (semid);
 } while (strncmp (shm_buff_inst->buffer, "quit", 4) != 0);

 /* 删除信号量 */
 del_sem (semid);

 /* 删除共享内存到当前进程地址空间中的映射 */
 if (shmdt (shared_memory) == 1) {
  perror ("shmdt");
  exit (1);
 }
 exit (0);
}

执行:
lsb@ubuntu:~/gx/wangluo$ ./msgsnd
Open queue 0
Enter some message to the queue(enter 'quit' to exit):写字端,开始写字
Enter some message to the queue(enter 'quit' to exit):对方在等待,但是无法会回写
Enter some message to the queue(enter 'quit' to exit):你好!!

*********************************************

《read操作》


/* customer.c */

#include "shm_com.h"
#include "sem_com.h"

int main ()
{
 void *shared_memory = NULL;
 struct shm_buff *shm_buff_inst;
 int shmid, semid;

 /* 获得信号量 */
 semid = semget (ftok (".", 'a'), 1, 0666);
 if (semid == -1) {
  perror ("Producer is'nt exist");
  exit (1);
 }

 /* 获得共享内存 */
 shmid = shmget (ftok (".", 'b'), sizeof (struct shm_buff), 0666 | IPC_CREAT);
 if (shmid == -1) {
  perror ("shmget");
  exit (1);
 }

 /* 将共享内存地址映射到当前进程地址空间 */
 shared_memory = shmat (shmid, (void *) 0, 0);
 if (shared_memory == (void *) -1) {
  perror ("shmat");
  exit (1);
 }
 printf ("Memory attached at %X\n", (int) shared_memory);
 /* 获得共享内存的映射地址 */
 shm_buff_inst = (struct shm_buff *) shared_memory;

 do {
  sem_p (semid);
  printf ("Shared memory was written by process %d :%s", shm_buff_inst->pid, shm_buff_inst->buffer);
  if (strncmp (shm_buff_inst->buffer, "quit", 4) == 0) {
   break;
  }
  shm_buff_inst->pid = 0;
  memset (shm_buff_inst->buffer, 0, SHM_BUFF_SZ);
  sem_v (semid);
 } while (1);

 /* 删除共享内存到当前进程地址空间中的映射 */
 if (shmdt (shared_memory) == -1) {
  perror ("shmdt");
  exit (1);
 }

 /* 删除共享内存 */
 if (shmctl (shmid, IPC_RMID, NULL) == -1) {
  perror ("shmctl(IPC_RMID)");
  exit (1);
 }
 exit (0);
}

执行:

lsb@ubuntu:~/gx/wangluo$ ./msgrcv
Open queue 0
The message from process 3361 : 写字端,开始写字
The message from process 3361 : 对方在等待,但是无法会▒回写
The message from process 3361 : 你好!!

 

原创粉丝点击