2024-2-26-进程线程通信作业

课上代码:

sem.h

#ifndef _SEM_H_
#define _SEM_H_

int open_sem(int semcount);
int P(int semid,int semno);
int V(int semid,int semno);
int del_sem(int semid);

#endif

sem.c

#include <myhead.h>
union semun
{
    int val;
    struct semid_ds *buf;
    unsigned short *array;
    struct seminfo *__buf;
};
int init_semno(int semid, int semno)
{
    union semun buf;

    printf("请输入要给编号为%d的灯设置的值:", semno);
    scanf("%d", &buf.val);

    if (semctl(semid, semno, SETVAL, buf) == -1)
    {
        perror("semctl error");
        return -1;
    }
    return 0;
}
int open_sem(int semcount)
{
    key_t key = -1;
    if ((key = ftok("/", 's')) == -1)
    {
        perror("ftok error");
        return -1;
    }
    int semid = -1;
    if ((semid = semget(key, semcount, IPC_CREAT | IPC_EXCL | 0664)) == -1)
    {
        if (errno == EEXIST)
        {
            semid = semget(key, semcount, IPC_CREAT | 0664);
            return semid;
        }
        perror("semget error");
        return -1;
    }
    for (int i = 0; i < semcount; i++)
    {
        init_semno(semid, i);
    }
    return semid;
}
int P(int semid, int semno)
{
    struct sembuf buf;
    buf.sem_num = semno;
    buf.sem_op = -1;
    buf.sem_flg = 0;
    if (semop(semid, &buf, 1) == -1)
    {
        perror("P error");
        return -1;
    }
    return 0;
}
int V(int semid, int semno)
{
    struct sembuf buf;
    buf.sem_num = semno;
    buf.sem_op = 1;
    buf.sem_flg = 0;
    if (semop(semid, &buf, 1) == -1)
    {
        perror("V error");
        return -1;
    }
    return 0;
}
int del_sem(int semid)
{
    if (semctl(semid, 0, IPC_RMID) == -1)
    {
        perror("delete error");
        return -1;
    }
    return 0;
}

shmsnd.c

#include <myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, char const *argv[])
{
    int semid=open_sem(2);

    key_t key = -1;
    if ((key = ftok("/", 's')) == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key =%d\n", key);
    int shmid = -1;
    if ((shmid = shmget(key, PAGE_SIZE, IPC_CREAT | 0664)) == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid =%d\n", shmid);
    char *addr = NULL;
    if ((addr = shmat(shmid, NULL, 0)) == (void *)-1)
    {
        perror("shmat error");
        return -1;
    }
    printf("addr =%p\n", addr);
    while (1)
    {
        P(semid,0);
        printf("请输入:>>>");
        fgets(addr, PAGE_SIZE, stdin);
        addr[strlen(addr) - 1] = 0;
        printf("数据输入成功\n");
        V(semid,1);
        if (strcmp(addr, "quit") == 0)
        {
            break;
        }
    }

    if (shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
    {
        perror("shmctl error");
    }

    return 0;
}

shmrcv.c

#include <myhead.h>
#include"sem.h"
#define PAGE_SIZE 4096
int main(int argc, char const *argv[])
{
    int semid = open_sem(2);
    key_t key = -1;
    if ((key = ftok("/", 's')) == -1)
    {
        perror("ftok error");
        return -1;
    }
    printf("key =%d\n", key);
    int shmid = -1;
    if ((shmid = shmget(key, PAGE_SIZE, IPC_CREAT | 0664)) == -1)
    {
        perror("shmget error");
        return -1;
    }
    printf("shmid =%d\n", shmid);
    char *addr = NULL;
    if ((addr = shmat(shmid, NULL, 0)) == (void *)-1)
    {
        perror("shmat error");
        return -1;
    }
    printf("addr =%p\n", addr);
    while (1)
    {
        P(semid, 1);
        printf("收到的数据为:%s\n", addr);

        if (strcmp(addr, "quit") == 0)
        {
            break;
        }
        V(semid, 0);
    }

    if (shmdt(addr) == -1)
    {
        perror("shmdt error");
        return -1;
    }

    return 0;
}

效果图:

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值