实验七 Linux进程间通信

  实验名称:Linux进程间通信

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

实验目的及要求

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

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

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

二、实验内容

所有文件汇总


文件汇总

Linux信号

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

7-1结果


7.1

7-2结果


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,编译并运行写出执行结果。


7.3

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

IPC方法—命名管道(FIFO)

输入程序7-4,7-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,编译执行并写出结果。


这里运行的sem1.头文件就不要编译了-。-

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


7.8 && 7.9

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


.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,编译执行并写出结果。


7.10 && 7.11

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

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

du.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 "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 <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#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,编译执行并写出结果。


7.12 && 7.13

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

7-1

#include <signal.h>

#include <stdio.h>

#include <unistd.h>

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 <signal.h>

#include <stdio.h>

#include <unistd.h>

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 <unistd.h>

#include <sys/types.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

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 <sys/types.h>

#include <sys/stat.h>

#include <string.h>

#include <stdio.h>

#include <errno.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdlib.h>

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 <sys/types.h>

#include <sys/stat.h>

#include <string.h>

#include <stdio.h>

#include <errno.h>

#include <fcntl.h>

#include <stdlib.h>

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 <sys/sem.h> */

#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 <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

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

#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 <stdio.h>

#include <sys/mman.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <signal.h>

#include <stdlib.h>

#include <string.h>

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

/* union semun is defined by including <sys/sem.h> */

#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 <stdio.h>

#include <sys/mman.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/sem.h>

#include <string.h>

#include <stdlib.h>

#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 <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#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 <unistd.h>

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/shm.h>

#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 <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <signal.h>

#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 <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include <signal.h>

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

}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341