Linux进程间通信——信号量2,利用信号量实现三个进程a,b,c分别输出“A“,“B“,“C“,要求输出的结果必须是”ABCABCABC...“

多个信号量

三个进程a,b,c分别输出"A","B","C",要求输出的结果必须是"ABCABCABC...";

思路:

代码演示:

cpp 复制代码
//sem.h
typedef union senum
{
    int val;
}SemUn;

int GetSem(int key,int initval[],int n); 
int DelSem(int semid);
int SemP(int semid,int index);
int SemV(int semid,int index);
cpp 复制代码
//sem.c
#include "sem.h"
#include <sys/sem.h>
#include <stdio.h>

int GetSem(int key,int initval[],int n)
{
    int semid=semget((key_t)key,n,0600|IPC_CREAT|IPC_EXCL);
    if(semid==-1)
    {   
        semid=semget((key_t)key,n,0600);
        if(semid==-1)
        {
            printf("semget error!\n");
            return -1; 
        }
    }   
    else
    {   
        int i=0;
        for(;i<n;i++)
        {
            SemUn data;
            data.val=initval[i];
            int res=semctl(semid,i,SETVAL,data);
            if(res==-1)
            {
                printf("semcil error");
                DelSem(semid);
                return -1; 
            }
        }
    }
        return semid;
}

int SemP(int semid,int index)
{
    struct sembuf buf;
    buf.sem_num=index;//第几个信号量S1,S2,S3
    buf.sem_op=-1;
    buf.sem_flg=SEM_UNDO;

    int res=semop(semid,&buf,1);
    if(res==-1)
    {
        printf("semop p error!\n");
        return -1;
    }
    return 0;
}

int SemV(int semid,int index)
{
    struct sembuf buf;
    buf.sem_num=index;//第几个信号量S1,S2,S3
    buf.sem_op=1;
    buf.sem_flg=SEM_UNDO;
    int res=semop(semid,&buf,1);
    if(res==-1)
    {
        printf("semop v error!\n");
        return -1;
    }
    return 0;
}

int DelSem(int semid)
{
    if(semctl(semid,0,IPC_RMID)==-1)
    {
        perror("semctl del error!\n");
        return -1;
    }
    return 0;
}
          
cpp 复制代码
//a.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"

int main()
{
    srand(time(NULL));
    int initval[]={1,0,0};
    int semid=GetSem(1234,initval,3);
    assert(semid!=-1);

    int count=0;
    while(count<5)
    {   
        SemP(semid,0);
        printf("A");
        fflush(stdout);
        int n=rand()%3;
        sleep(n);
        SemV(semid,1);
        count++;
    }   
    exit(0);
}
cpp 复制代码
//b.c
include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"

int main()
{
    srand(time(NULL));
    int initval[]={1,0,0};
    int semid=GetSem(1234,initval,3);
    assert(semid!=-1);

    int count=0;
    while(count<5)
    {   
        SemP(semid,1);
        printf("B");
        fflush(stdout);
        int n=rand()%3;
        sleep(n);
        SemV(semid,2);
        count++;
    }   
    exit(0);
}
cpp 复制代码
//c.c
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <unistd.h>
#include "sem.h"

int main()
{
    srand(time(NULL));
    int initval[]={1,0,0};
    int semid=GetSem(1234,initval,3);
    assert(semid!=-1);

    int count=0;
    while(count<5)
    {   
        SemP(semid,2);
        printf("C");
        fflush(stdout);
        int n=rand()%3;
        sleep(n);
        SemV(semid,0);
        count++;
    }   
    DelSem(semid);//最后一个退出的销毁
    exit(0);
}

运行结果:

相关推荐
一技安身5 小时前
【信创】银河麒麟V10、统信UOS解压7Z文件
linux·运维·服务器
奔跑的架构师6 小时前
[A-50]ARMv9/v8-DVFS系统架构
linux·arm开发·架构·系统架构·arm
迷途呀6 小时前
CI/CD 自动化部署实践:让代码提交后自动上线
linux·运维·nginx·ci/cd·自动化
赴生-6 小时前
Liunx 操作系统 进程概念(上)
linux
binqian7 小时前
【linux】OpenSSH升级文档
linux·运维·网络
吴声子夜歌7 小时前
Shell编程——if条件语句
linux·运维·shell
Dawn-bit7 小时前
Linux 运维基础扩展:跳板机、堡垒机与物理服务器全流程
linux·运维·服务器·云计算·运维开发
新时代牛马7 小时前
Linux 定时任务:crontab、anacron 与systemd timer
linux·运维·服务器
mounter6258 小时前
Linux 7.2 引入更灵活的块设备错误注入机制
linux·linux kernel·kernel·disk·error injection
cpolar技术支持8 小时前
Docker 容器启动失败怎么查?端口、日志、权限与网络排障完整教程
linux·docker·容器·cpolar·网络排障