共享内存和信号量

接受端

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<sys/ipc.h>

void  handler_SIGUSR1(int sig, siginfo_t *info, void *ucontext)
{
    key_t key;//创建钥匙
    int shmid;//存放共享内存id
    if((key = ftok(".",124))==-1)//获得这块内存的钥匙,发送端必须有一样的钥匙才能操作这块共享内存
    {
        perror("ftok");
        exit(-1);
       
       
    if((shmid = shmget(key,1024,0777|IPC_CREAT)) == -1)//创建共享内存 0777可读可写可执行,大小必须字节为单位
    {//打开或创建
        perror("shmget");
        exit(-1);
    }
    if((info->si_ptr = (void *)shmat(shmid,NULL,0)) ==(void*) -1)
    {//关键一步 将信号结构体里存放指针的变量指向开辟的共享内存
        perror("shmat");
        exit(-1);
    }
    if(sig == SIGUSR1)//判断该信号是否到来
    {
        printf("receive signal:%d data:%s",info->si_signo,
        (char*)info->si_ptr);//info 结构体里的si_ptr 是void类型需要强制转换
    }

}

void  handler_SIGUSR2(int sig, siginfo_t * info, void * ucontext)
{

    if(sig == SIGUSR2)
    {
    printf("received signal:%d data:%d\n",info->si_signo,info->si_int);//si_signo信号在系统中的编号
    }
}
int main(int argc,char *argv[])
{
    printf("pid = %d\n",getpid());

    struct sigaction act1,act2;//创建两个信号结构体分别来接收两个信号
 
    act1.sa_sigaction = handler_SIGUSR1;//指定调用的函数
    act1.sa_flags = SA_SIGINFO;//对信号处理程序 提供附加信息

    sigemptyset(&act1.sa_mask);//清空信号集
   
    if(sigaction(SIGUSR1,&act1,NULL) == -1)
    {
        perror("sigaction");
        exit(-1);
    }
    act2.sa_sigaction = handler_SIGUSR2;
    act2.sa_flags = SA_SIGINFO;

    sigemptyset(&act2.sa_mask);

    if(sigaction(SIGUSR2,&act2,NULL) == -1)
    {
        perror("sigaction");
                exit(-1);

    }
    while(1);
    return 0;
}
发送端
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/ipc.h>
 #include<sys/types.h>
#include<string.h>

int main(int argc,char *argv[])
{
    if(argc != 2)
    {
        printf("intput error!\n");
        exit(-1);
    }
//判断是否有两个参数
    int pid = atoi(argv[1]);//id是第二个参数
    union sigval sig_val;//定义两个联合体,存放两个需要发送的数据
    union sigval sig_val1;

    key_t key;
    int shmid;
    if((key = ftok(".",124))==-1)
    {
        perror("ftok");
        exit(-1);
    }
    if((shmid = shmget(key,1024,0777|IPC_CREAT)) == -1)//打开或创建内存共享内存空间
    {
        perror("shmget");
        exit(-1);
    }
    if((sig_val1.sival_ptr =(void*)shmat(shmid,NULL,0)) == (void*)-1)//将联合体中的数据挂载在共享内存中
    {
        perror("shmat");
        exit(-1);
    }
    sig_val.sival_int = 100;//发送的附加信息

    strcpy(sig_val1.sival_ptr,"jia you long cheng yue\n");//将需要发送的字符串发送到挂载到在共享内存中的联合体
       
    while(1)
    {
        sleep(1);

        sig_val.sival_int++;

        if(sigqueue(pid,SIGUSR1,sig_val1) == -1)//pid是接收端的pid 发送SIFGUSR1信号,将val1的内容一起发出去
        {
            perror("sigqueue");
            exit(-1);
        }

        sleep(1);

        if(sigqueue(pid,SIGUSR2,sig_val) == -1)
        {
            perror("sigqueue");
            exit(-1);
        }

        sleep(1);

    }
    return 0;
}
posted @   信号编程好难  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示