实验七 Linux进程间通信

  实验名称:Linux进程间通信

所有的文件 和 报告 在 :https://github.com/menghuanali/Linux7

实验目的及要求

学习和掌握Linux信号概念,并能使用系统调用完成电子表计时程序。

学习和掌握Linux进程间通信的IPC方法。

学习和掌握利用信号量实现进程间的同步通信。

二、实验内容

所有文件汇总


实验七 Linux进程间通信_第1张图片
文件汇总

Linux信号

输入程序7-1,7-2编译并运行写出执行结果。

7-1结果


实验七 Linux进程间通信_第2张图片
7.1

7-2结果


实验七 Linux进程间通信_第3张图片
7.3

可以看到,第一次按下终止命令(ctrl+c)时,进程并没有被终止,面是输出OUCH! - I got signal 2,因为SIGINT的默认行为被signal函数改变了,当进程接受到信号SIGINT时,它就去调用函数ouch去处理,注意ouch函数把信号SIGINT的处理方式改变成默认的方式,所以当你再按一次ctrl+c时,进程就像之前那样被终止了。

对比执行结果,你得到的启示是:

区别在于,7_2中ouch函数中又进行安装信号函数。即当ouch函数捕获外部中断的SGIINT信号后,改变安装信号函数(接受中断信号,进程结束)利用Linux信号SIGALAM,设计并实现电子表程序。

IPC方法—管道

输入程序7-3,编译并运行写出执行结果。


实验七 Linux进程间通信_第4张图片
7.3

双向管道实现聊天室功能!

IPC方法—命名管道(FIFO)

输入程序7-4,7-5编译并运行写出执行结果。


实验七 Linux进程间通信_第5张图片
7.4 && 7.5

本程序是一个使用FIFO(命名管道)进行进程间通信的典型程序

lucy.c创建了FIFO write_fifo用于向程序peter.c发送信息;

peter.c程序创建了FIFO read-fifo,用于向lucy.c发送消息。

先运行peter.c 再运行lucy.c


IPC方法—信号量

输入程序7-6 semun.h和7-7 sem1.c,编译执行并写出结果。


实验七 Linux进程间通信_第6张图片
这里运行的sem1.头文件就不要编译了-。-

输入程序7-8和7-9,编译执行并写出结果。


实验七 Linux进程间通信_第7张图片
7.8 && 7.9

创建 shares-file文件,实现双方通信文件里乱码


实验七 Linux进程间通信_第8张图片
.shared_file

程序7-8和7-9中哪段代码实现了共享,描述实现内存映射的主要函数的参数意义

fd = open(filenm, O_RDWR | O_CREAT); 

mmap_addr = (char*)mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

mmap函数中,0表示有系统分配映射内存的地址;4096表示映射内存大小为4096B ,

IPC方法—共享内存

输入程序7-10和7-11,编译执行并写出结果。


实验七 Linux进程间通信_第9张图片
7.10 && 7.11

简述程序7-10和7-11,是否实现了共享内存互斥访问,如何实现?

实现了共享实现了内存互斥访问,利用结构体中的变量wrritten_by_you。1为读,0为写

du.c

#include

#include

#include

#include

#include

#include

#include

#include "shm_com.h"

int main(void)

{

   int running=1;

void *shared_memory=(void *)0;

struct shared_use_st *shared_stuff;

int shmid;

/*创建共享内存*/

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

if(shmid==-1)

{

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

exit(EXIT_FAILURE);

}

/*映射共享内存*/

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

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

{

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

exit(EXIT_FAILURE);

}

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

/*让结构体指针指向这块共享内存*/

shared_stuff=(struct shared_use_st*)shared_memory;

/*控制读写顺序*/

shared_stuff->written_by_you=0;

/*循环的从共享内存中读数据,直到读到“end”为止*/

while(running)

{

 if(shared_stuff->written_by_you)

  {

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

 sleep(1);  //读进程睡一秒,同时会导致写进程睡一秒,这样做到读了之后再写

 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(EXIT_FAILURE);

}

      exit(EXIT_SUCCESS);

}

xie.c

#include

#include

#include

#include

#include

#include

#include

#include "shm_com.h"

int main(void)

{

   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(structshared_use_st),0666|IPC_CREAT);

if(shmid==-1)

{

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

exit(EXIT_FAILURE);

}

/*映射共享内存*/

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

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

{

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

exit(EXIT_FAILURE);

}

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

/*让结构体指针指向这块共享内存*/

shared_stuff=(struct shared_use_st*)shared_memory;

/*循环的向共享内存中写数据,直到写入的为“end”为止*/

while(running)

{

  while(shared_stuff->written_by_you==1)

{

  sleep(1);//等到读进程读完之后再写

printf("waiting forclient...\n");

}

printf("Ener some text:");

fgets(buffer,BUFSIZ,stdin);

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

shared_stuff->written_by_you=1;

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

{

  running=0;  //结束循环

}

}

/*删除共享内存*/

if(shmdt(shared_memory)==-1)

{

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

exit(EXIT_FAILURE);

}

exit(EXIT_SUCCESS);

}

shm_com.h

#define TEXT_SZ 2048

struct shared_use_st

{

   int written_by_you;

char some_text[TEXT_SZ];

};

IPC方法—消息队列

输入程序7-12和7-13,编译执行并写出结果。


实验七 Linux进程间通信_第10张图片
7.12 && 7.13

实验主要流程、基本操作或核心代码、算法片段

7-1

#include

#include

#include

void ouch(int sig)

{

    printf("OUCH! - I got signal %d\n", sig);

}

int main()

{

    struct sigaction act;

act.sa_handler = ouch;

//创建空的信号屏蔽字,即不屏蔽任何信息

    sigemptyset(&act.sa_mask);

    act.sa_flags = 0;

    sigaction(SIGINT, &act, 0);

  while(1) {

    printf("Hello World!\n");

    sleep(1);

  }

}

7-2

#include

#include

#include

void ouch(int sig)

{

    printf("OUCH! - I got signal %d\n", sig);

    (void) signal(SIGINT, SIG_DFL);

}

int main()

{

    (void) signal(SIGINT, ouch);

    while(1) {

        printf("Hello World!\n");

        sleep(1);

    }

}

7-3—lucyToPeter.c

#include

#include

#include

#include

#include

int main()

{

        int pipe1_fd[2], pipe2_fd[2];

        char parent_buf[256], child_buf[256];

        int len;

        int child_status;

        if(pipe(pipe1_fd)<0)

        {

                printf("pipe1 create error\n");

                return -1;

        }

        if(pipe(pipe2_fd)<0)

        {

                printf("pipe2 create error\n");

                return -1;

        }

        if(fork()==0)  //child

        {

                printf("\n");

                //pipe1_fd[0] is used to read, pipe2_fd[1] is used to write

                close(pipe1_fd[1]);

                close(pipe2_fd[0]);

                while(1)

                {

                        len = read(pipe1_fd[0], child_buf, 255);

                        child_buf[len] = '\0';

                        printf("peter_Lucy: %s\n", child_buf);

                printf("Peter: ");

                fgets(child_buf, 256, stdin);

child_buf[strlen(child_buf)-1] = '\0';

                if (strncmp(child_buf,"quit", 4) == 0) {

                close(pipe1_fd[0]);

                close(pipe2_fd[1]);

                        exit(0);

                }

write(pipe2_fd[1], child_buf, strlen(child_buf));

sleep(1);

}

                close(pipe1_fd[0]);

                close(pipe2_fd[1]);

                exit(0);

    }

        else {  //parent

                //pipe1_fd[1] is used to write, pipe2_fd[0] is used to read

                close(pipe1_fd[0]);

                close(pipe2_fd[1]);

                while (1) {

printf("Lucy: ");

fgets(parent_buf, 256, stdin);

if (strncmp(parent_buf,"quit", 4) == 0) {

        close(pipe1_fd[1]);

        close(pipe2_fd[0]);

                        exit(0);

}

write(pipe1_fd[1],parent_buf,strlen(parent_buf));

sleep(1);

                        len = read(pipe2_fd[0],parent_buf,255);

                        parent_buf[len] = '\0';

                        printf("Lucy_peter: %s\n", parent_buf);

                }

        close(pipe1_fd[1]);

        close(pipe2_fd[0]);

        wait(&child_status);

        exit(0);

        }

}

7-4—lucy.c

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

        char write_fifo_name[] = "write-fifo";

        char read_fifo_name[] = "read-fifo";

        int write_fd, read_fd;

        char buf[256];

        int len;

        struct stat stat_buf;

        int ret = mkfifo(write_fifo_name, S_IRUSR | S_IWUSR);

        if ( ret == -1) {

                printf("Fail to create FIFO %s: %s", write_fifo_name, strerror(errno));

                exit(-1);

        }

        write_fd = open(write_fifo_name, O_WRONLY);

        if (write_fd == -1) {

                printf("Fail to open FIFO %s: %s", write_fifo_name, strerror(errno));

                exit(-1);

        }

        while ((read_fd = open(read_fifo_name, O_RDONLY)) == -1) {

                sleep(1);

        }

        while (1) {

                printf("Lucy: ");

                fgets(buf, 256, stdin);

                buf[strlen(buf)-1] = '\0';

                if (strncmp(buf,"quit", 4) == 0) {

                        close(write_fd);

                        unlink(write_fifo_name);

                        close(read_fd);

                        exit(0);

                }

                write(write_fd, buf, strlen(buf));

                len = read(read_fd, buf, 256);

                if ( len > 0) {

                        buf[len] = '\0';

                        printf("Peter: %s\n", buf);

                }

        }

}

7-5—peter.c

#include

#include

#include

#include

#include

#include

#include

int main()

{

        char write_fifo_name[] = "read-fifo";

        char read_fifo_name[] = "write-fifo";

        int write_fd, read_fd;

        char buf[256];

        int len;

        int ret = mkfifo(write_fifo_name, S_IRUSR | S_IWUSR);

        if ( ret == -1) {

                printf("Fail to create FIFO %s: %s", write_fifo_name, strerror(errno));

                exit(-1);

        }

        while ((read_fd = open(read_fifo_name, O_RDONLY)) == -1) {

                sleep(1);

        }

        write_fd = open(write_fifo_name, O_WRONLY);

        if (write_fd == -1) {

                printf("Fail to open FIFO %s: %s", write_fifo_name, strerror(errno));

                exit(-1);

        }

        while (1) {

                len = read(read_fd, buf, 256);

                if ( len > 0) {

                        buf[len] = '\0';

                        printf("Lucy: %s\n", buf);

                }

                printf("Peter: ");

                fgets(buf, 256, stdin);

                buf[strlen(buf)-1] = '\0';

                if (strncmp(buf,"quit", 4) == 0) {

                        close(write_fd);

                        unlink(write_fifo_name);

                        close(read_fd);

                        exit(0);

                }

                write(write_fd, buf, strlen(buf));

        }

}

7-6—semun.h

#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)

    /* union semun is defined by including */

#else

    /* according to X/OPEN we have to define it ourselves */

    union semun {

        int val;                    /* value for SETVAL */

        struct semid_ds *buf;      /* buffer for IPC_STAT, IPC_SET */

        unsigned short int *array;  /* array for GETALL, SETALL */

        struct seminfo *__buf;      /* buffer for IPC_INFO */

    };

#endif

7-7—sem1.c

#include

#include

#include

#include

#include

#include

//应用程序必须再定义一遍

#include "semun.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 = 'O';

    srand((unsigned int)getpid());

    //创建信号量集,信号量集id是1234,信号量集中只有一个信号量,一个信号量代表一种共享资源[[stdout]]

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

    printf("semid = %d\n",sem_id);

    if (argc > 1) { //必须要有一个进程启动时argc大于1,来set_semvalue(),否则参数argc=1的进程会一直阻塞在line 53:semaphore_p()

        if (!set_semvalue()) { //程序第一次被调用,初始化信号量

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

            exit(EXIT_FAILURE);

        }

//设置要输出到屏幕中的信息,即其参数的第一个字符

        op_char = 'X';

        sleep(5);

    }

/* Then we have a loop which enters and leaves the critical section ten times.

There, we first make a call to semaphore_p which sets the semaphore to wait, as

this program is about to enter the critical section. */

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

//进入临界区

        if (!semaphore_p()) exit(EXIT_FAILURE);

//向屏幕中输出数据

        printf("%c", op_char);fflush(stdout);

//清理缓冲区,然后休眠随机时间

        pause_time = rand() % 3;

        sleep(pause_time);

//离开临界区前再一次向屏幕输出数据

        printf("%c", op_char);fflush(stdout);

//离开临界区,休眠随机时间后继续循环

        if (!semaphore_v()) exit(EXIT_FAILURE);

        pause_time = rand() % 2;

        sleep(pause_time);

    }   

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

    if (argc > 1) {   

        sleep(10);

        del_semvalue();

    }

    exit(EXIT_SUCCESS);

}

/* The function set_semvalue initializes the semaphore using the SETVAL command in a semctl call. We need to do this before we can use the semaphore. */

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);

}

/* The del_semvalue function has almost the same form, except the call to semctl uses the command IPC_RMID to remove the semaphore's ID. */

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");

}

/* semaphore_p changes the semaphore by -1 (waiting). */

static int semaphore_p(void)

{

    struct sembuf sem_b;

    sem_b.sem_num = 0;

    sem_b.sem_op = -1; /* P() */

    sem_b.sem_flg = SEM_UNDO;

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

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

        return(0);

    }

    return(1);

}

/* semaphore_v is similar except for setting the sem_op part of the sembuf structure to 1, so that the semaphore becomes available. */

static int semaphore_v(void)

{

    struct sembuf sem_b;

    sem_b.sem_num = 0;

    sem_b.sem_op = 1; /* V() */

    sem_b.sem_flg = SEM_UNDO;

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

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

        return(0);

    }

    return(1);

}

7-8—lucy2.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#if defined(_GNU_LIBRARY_) && !defined(_SEM_SEMUN_UNDEFINED)

/* union semun is defined by including */

#else

/* according to X/OPEN we have to define it ourselves */

union semun {

      int val;                  /* value for SETVAL */

      struct semid_ds *buf;    /* buffer for IPC_STAT, IPC_SET */

      unsigned short *array;    /* array for GETALL, SETALL */

                                /* Linux specific part: */

      struct seminfo *_buf;    /* buffer for IPC_INFO */

};

#endif

#define PROJID 0xFF

int semid;

void terminate_handler(int signo)

{

semctl(semid, 0, IPC_RMID);

exit(0);

}

int main(void)

{

char filenm[] = "shared-file";

char zero_blk[4096];

char * mmap_addr;

int fd;

key_t semkey;

struct sembuf getsem, setsem;

union semun seminit;

int ret;

semkey = ftok(filenm, PROJID);

if (semkey == -1) {

perror("ftok error: ");

exit(-1);

}

semid = semget(semkey, 2, IPC_CREAT | IPC_EXCL | 0666);

if (semid == -1) {

perror("semget error: ");

exit(-1);

}

seminit.val = 0;

semctl(semid, 0, SETVAL, seminit);

semctl(semid, 1, SETVAL, seminit);

getsem.sem_num = 1;

    getsem.sem_op = -1;

    getsem.sem_flg = SEM_UNDO;

setsem.sem_num = 0;

    setsem.sem_op = 1;

    setsem.sem_flg = SEM_UNDO;

signal(SIGINT, terminate_handler);

signal(SIGTERM, terminate_handler);

memset(zero_blk, 0, 4096);

fd = open(filenm, O_RDWR | O_CREAT);

        if (fd == -1) {

perror("open error: ");

semctl(semid, 0, IPC_RMID);

exit(-1);

}

write(fd, zero_blk, 4096);

mmap_addr = (char *)mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (mmap_addr == (char *)-1) {

perror("mmap error: ");

semctl(semid, 0, IPC_RMID);

close(fd);

exit(-1);

}

while (1) {

printf("Lucy: ");

fgets(mmap_addr, 256, stdin);

if (strncmp("quit", mmap_addr, 4) == 0) {

if (munmap(mmap_addr, 4096) == -1) {

perror("munmap error: ");

}

close(fd);

semctl(semid, 0, IPC_RMID);

exit(0);

}

mmap_addr[strlen(mmap_addr)-1] = '\0';

ret = semop(semid, &setsem, 1);

if (ret == -1) {

perror("semop error: ");

}

ret = semop(semid, &getsem, 1);

if (ret == -1) {

perror("semop error: ");

}

printf("Peter: %s\n", mmap_addr);

}

}

7-9—peter2.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define PROJID 0xFF

int main(void)

{

char filenm[] = "shared-file";

char * mmap_addr;

int fd, semid;

key_t semkey;

struct sembuf getsem, setsem;

semkey = ftok(filenm, PROJID);

if (semkey == -1) {

perror("ftok error: ");

exit(-1);

}

semid = semget(semkey, 0, 0);

if (semid == -1) {

perror("semget error: ");

exit(-1);

}

getsem.sem_num = 0;

        getsem.sem_op = -1;

        getsem.sem_flg = SEM_UNDO;

setsem.sem_num = 1;

        setsem.sem_op = 1;

        setsem.sem_flg = SEM_UNDO;

fd = open(filenm, O_RDWR | O_CREAT);

        if (fd == -1) {

perror("open error: ");

semctl(semid, 0, IPC_RMID);

exit(-1);

}

mmap_addr = (char *)mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

if (mmap_addr == (char *)-1) {

perror("mmap error: ");

close(fd);

exit(-1);

}

while (1) {

semop(semid, &getsem, 1);

printf("Lucy: %s\n", mmap_addr);

printf("Peter: ");

fgets(mmap_addr, 256, stdin);

if (strncmp("quit", mmap_addr, 4) == 0) {

mmap_addr[strlen(mmap_addr)-1] = '\0';

semop(semid, &setsem, 1);

if (munmap(mmap_addr, 4096) == -1) {

perror("munmap error: ");

}

close(fd);

exit(0);

}

mmap_addr[strlen(mmap_addr)-1] = '\0';

semop(semid, &setsem, 1);

}

}

7-10(可用上面的du.c代替)

/* Our first program is a consumer. After the headers the shared memory segment

(the size of our shared memory structure) is created with a call to shmget,

with the IPC_CREAT bit specified. */

#include

#include

#include

#include

#include

#include

#include

#include "shm_com.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(EXIT_FAILURE);

    }

/*映射共享内存*/

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

    if (shared_memory == (void *)-1) {

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

        exit(EXIT_FAILURE);

    }

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

/* The next portion of the program assigns the shared_memory segment to shared_stuff,

which then prints out any text in written_by_you. The loop continues until end is found

in written_by_you. The call to sleep forces the consumer to sit in its critical section,

which makes the producer wait. */

/*让结构体指针指向这块共享内存*/

shared_stuff = (struct shared_use_st *)shared_memory;

/*控制读写顺序*/

shared_stuff->written_by_you = 0;

/*循环的从共享内存中读数据,直到读到“end”为止*/

    while(running) {

        if (shared_stuff->written_by_you) {

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

            sleep(1); //读进程睡1秒,同时会导致写进程睡一秒,这样做到读了之后再写

            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(EXIT_FAILURE);

    }

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

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

        exit(EXIT_FAILURE);

    }

    exit(EXIT_SUCCESS);

}

7-11(可用上面的xie.c代替)

/* The second program is the producer and allows us to enter data for consumers.

It's very similar to shm1.c and looks like this. */

//写进程

#include

#include

#include

#include

#include

#include

#include

#include "shm_com.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(EXIT_FAILURE);

    }

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

    if (shared_memory == (void *)-1) {

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

        exit(EXIT_FAILURE);

    }

    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 (strncmp(buffer, "end", 3) == 0) {

                running = 0;

        }

    }

    if (shmdt(shared_memory) == -1) {

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

        exit(EXIT_FAILURE);

    }

    exit(EXIT_SUCCESS);

}

shm_com.h

#define TEXT_SZ 2048

struct shared_use_st

{

    int written_by_you;

char some_text[TEXT_SZ];

};

7-12—lucy3.c

#include

#include

#include

#include

#include

#include

#include

#define PROJID 0xFF

#define SNDMSG 1

#define RCVMSG 2

int mqid;

void terminate_handler(int signo)

{

msgctl(mqid, IPC_RMID, NULL);

exit(0);

}

int main(void)

{

char filenm[] = "shared-file";

key_t mqkey;

struct msgbuf {

        long mtype;    /* message type, must be > 0 */

            char mtext[256];  /* message data */

  }msg;

int ret;

mqkey = ftok(filenm, PROJID);

if (mqkey == -1) {

perror("ftok error: ");

exit(-1);

}

mqid = msgget(mqkey, IPC_CREAT | IPC_EXCL | 0666);

if (mqid == -1) {

perror("msgget error: ");

exit(-1);

}

signal(SIGINT, terminate_handler);

signal(SIGTERM, terminate_handler);

while (1) {

printf("Lucy: ");

fgets(msg.mtext, 256, stdin);

if (strncmp("quit", msg.mtext, 4) == 0) {

msgctl(mqid, IPC_RMID, NULL);

exit(0);

}

msg.mtext[strlen(msg.mtext)-1] = '\0';

msg.mtype = SNDMSG;

msgsnd(mqid, &msg, strlen(msg.mtext) + 1, 0);

msgrcv(mqid, &msg, 256, RCVMSG, 0);

printf("Peter: %s\n", msg.mtext);

}

}

7-13—peter3.c

#include

#include

#include

#include

#include

#include

#include

#define PROJID 0xFF

#define SNDMSG 1

#define RCVMSG 2

int main(void)

{

char filenm[] = "shared-file";

int mqid;

key_t mqkey;

struct msgbuf {

        long mtype;    /* message type, must be > 0 */

                char mtext[256];  /* message data */

        }msg;

int ret;

mqkey = ftok(filenm, PROJID);

if (mqkey == -1) {

perror("ftok error: ");

exit(-1);

}

mqid = msgget(mqkey, 0);

if (mqid == -1) {

perror("msgget error: ");

exit(-1);

}

while (1) {

msgrcv(mqid, &msg, 256, SNDMSG, 0);

printf("Lucy: %s\n", msg.mtext);

printf("Peter: ");

fgets(msg.mtext, 256, stdin);

if (strncmp("quit", msg.mtext, 4) == 0) {

exit(0);

}

msg.mtext[strlen(msg.mtext)-1] = '\0';

msg.mtype = RCVMSG;

msgsnd(mqid, &msg, strlen(msg.mtext) + 1, 0);

}

}

你可能感兴趣的:(实验七 Linux进程间通信)