zoukankan      html  css  js  c++  java
  • Linux程序设计:进程通信

     

    日期:忘了。

    关键词:Linux程序设计;System-V;进程通信;共享内存;消息队列。

    一、共享内存

     

    1.1 基本知识

    (待补充)

     

    1.2 代码

    一个基于share memory实现的客户-服务模型。

    • shm_comm.h

    #define TEXT_SZ 2048

    struct shared_use_st

    {

        int written_by_you;

        char some_text[TEXT_SZ];

    };

    typedef struct shared_use_st shared_use_st;

    • shm1.c

     

    #include <unistd.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <sys/shm.h>

    #include "shm_com.h"

     

    int main()

    {

        int running = 1;

        void *shm_ptr = NULL;

        struct shared_use_st *shared_stuff;

        int shmid;

     

        srand((unsigned int)getpid());

     

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

        printf("shmid = %x ", shmid);

        if (shmid == -1)

        {

            fprintf(stderr, "shmget fail ");

            exit(EXIT_FAILURE);

        }

        shm_ptr = shmat(shmid, NULL, 0);

        //该值应该是shm在当前进程空间中的虚拟地址,而不是shm真实的物理地址

        //所以shm1shm2的返回值不一样

     

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

        {

            fprintf(stderr, "shmat failed ");

            exit(EXIT_FAILURE);

        }

     

        printf("Memory attached at %p ", shm_ptr);

     

        shared_stuff = (struct shared_use_st *)shm_ptr;

        shared_stuff->written_by_you = 0;

        while (running)

        {

            if (shared_stuff->written_by_you)

            {

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

                sleep(5);

                shared_stuff->written_by_you = 0;

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

                {

                    running = 0;

                }

            }

        }

     

        if(shmdt(shm_ptr) == -1)

        {

            fprintf(stderr, "shmdt failed ");

            exit(EXIT_FAILURE);

        }

     

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

        {

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

            exit(EXIT_FAILURE);

        }

        exit(EXIT_SUCCESS);

    }

     

    • shm2.c

     

    #include <unistd.h>

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <sys/shm.h>

    #include "shm_com.h"

     

    int main()

    {

        int running = 1;

        void *shm_ptr = NULL;

        struct shared_use_st *share_stuff;

        char buff[TEXT_SZ];

        int shmid;

     

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

        printf("shmid = %x ", shmid);

        if(shmid == -1)

        {

            fprintf(stderr, "shmget failed ");

            exit(EXIT_FAILURE);

        }

     

        shm_ptr = shmat(shmid, NULL, 0);

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

        {

            fprintf(stderr, "shmat failed ");

            exit(EXIT_FAILURE);

        }

        printf("Memory attached at %p ", shm_ptr);

     

        share_stuff = (struct shared_use_st*)shm_ptr;

     

        while(running)

        {

            if(share_stuff->written_by_you == 1)

            {

                sleep(1);

                printf("waiting for client ");

            }

            printf("Enter texts:");

            fgets(buff, TEXT_SZ, stdin);

            strncpy(share_stuff->some_text, buff, TEXT_SZ);

            share_stuff->written_by_you = 1;

              

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

            {

                running = 0;

            }

        }

     

        if(shmdt(shm_ptr) == -1)

        {

            fprintf(stderr, "shmdt failed ");

            exit(EXIT_FAILURE);

        }

        exit(EXIT_SUCCESS);

     

    }

    • 运行结果

    二、消息队列

    2.1 基本知识

    待补充。

    2.2 代码

    • msg1.c

    #include <stdlib.h>

    #include <stdio.h>

    #include <string.h>

    #include <errno.h>

    #include <unistd.h>

     

    #include <sys/msg.h>

    struct msg_t

    {

        long int msg_type;

        char content[BUFSIZ];

    };

     

    int main()

    {

        int running = 1;

        int msgid;

        long int msg_to_receive = 0; //决定队列消息优先级,0表示获取队列第一个可用消息

        struct msg_t msg;

     

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

        printf("msgid = %d ", msgid);

        if (msgid == -1)

        {

            fprintf(stderr, "msgget failed ");

            exit(EXIT_FAILURE);

        }

     

        while (running)

        {

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

            {

                fprintf(stderr, "msgrcv failde ");

                exit(EXIT_FAILURE);

            }

            printf("You wrote %s", msg.content);

            if(strncmp(msg.content, "end", 3) == 0)

                running = 0;

        }

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

        {

            fprintf(stderr, "msgcntl failed ");

            exit(EXIT_FAILURE);

        }

        exit(EXIT_SUCCESS);

     

    }

     

    • msg2.c

     

    #include <stdlib.h>

    #include <stdio.h>

    #include <string.h>

    #include <errno.h>

    #include <unistd.h>

    #include <sys/msg.h>

    #define MAX_TEXT 512

    struct msg_t

    {

        long int msg_type;

        char content[BUFSIZ];

    };

     

    int main()

    {

        int running = 1;

        struct msg_t msg;

        int msgid;

        char buffer[BUFSIZ];

     

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

        printf("msgid = %d ", msgid);

     

        if (msgid == -1)

        {

            fprintf(stderr, "msgget failed ");

            exit(EXIT_FAILURE);

        }

     

        while (running)

        {

            printf("Enter texts:");

            fgets(buffer, BUFSIZ, stdin);

            msg.msg_type = 1;

            strcpy(msg.content, buffer);

     

            if(msgsnd(msgid, (void *)&msg, BUFSIZ, 0) == -1)

            {

                fprintf(stderr, "msgsnd failed ");

                exit(EXIT_FAILURE);

            }

            if(strncmp(msg.content, "end", 3) == 0)

            {

                running = 0;

            }

        }

     

        exit(EXIT_SUCCESS);

    }

    • 运行结果

    三、信号量

    3.1 基本知识

    待补充。

    3.2 代码

    • 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

     

     

    • sema.c

    #include <stdio.h>

    #include <unistd.h>

    #include <stdlib.h>

    #include <sys/sem.h>

    #include "semun.h"

     

    static int sem_id;

    static int set_semvalue()

    {

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

    {

        union semun sem_union;

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

            fprintf(stderr, "Fail to delete semaphore ");

    }

    static int sema_p()

    {

        struct sembuf sem_b;

        sem_b.sem_num = 0;//信号量编号,除非是一组信号量,否则0

        sem_b.sem_op = -1;//-1操作

        sem_b.sem_flg = SEM_UNDO;//与操作系统对信号量的操作相关,一般是UNDO

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

        {

            fprintf(stderr, "sema_p failed ");

            return 0;

        }

        return 1;

    }

    static int sema_v()

    {

        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, "sema_v failed ");

            return 0;

        }

        return 1;

    }

     

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

    {

        int i;

        int pause_time;

        char op_char = 'O';

        srand((unsigned int)getpid());

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

        if (argc > 1)

        {

            if(set_semvalue() == 0)

            {

                fprintf(stderr, "init fail ");

                exit(EXIT_FAILURE);

            }

            op_char = 'X';

            sleep(2);

        }

     

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

        {

            if (sema_p() == 0)

                exit(EXIT_FAILURE);

            printf("%c", op_char);

            fflush(stdout);

     

            pause_time = rand() % 3;

            sleep(pause_time);

            printf("%c", op_char);

            fflush(stdout);

     

            if (!sema_v())

                exit(EXIT_FAILURE);

            pause_time = rand() % 2;

            sleep(pause_time);

        }

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

        if (argc > 1)

        {

            sleep(10);

            del_semvalue();

        }

        exit(EXIT_SUCCESS);

    }

  • 相关阅读:
    Asp.net 弹出对话框基类 (输出alet警告框)
    Request.ServerVariables获取环境变量
    Asp.net 字符串操作基类(安全,替换,分解等)
    asp.net 取得远程的IP地址和浏览器类型
    存储过程得到三个值
    弹出无边框网页的Javscrpt代码
    .net打包自动安装数据库!
    精妙Sql语句
    关于跨语言站点搜索结果非预期的问题
    SharePoint服务器场环境安装升级补丁的详细步骤
  • 原文地址:https://www.cnblogs.com/sinkinben/p/10793089.html
Copyright © 2011-2022 走看看