消息队列,共享内存
This commit is contained in:
		
							parent
							
								
									e6757b9935
								
							
						
					
					
						commit
						49d2f0cabb
					
				
							
								
								
									
										46
									
								
								day5/consumer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								day5/consumer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
// 消费者
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
typedef struct data
 | 
			
		||||
{
 | 
			
		||||
    char data[32];
 | 
			
		||||
    int flag;
 | 
			
		||||
} Data;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    printf("consumer\n");
 | 
			
		||||
 | 
			
		||||
    key_t key = ftok("/", 15);
 | 
			
		||||
    if (key == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("ftok");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Data *data_buf = (Data *)shmat(shmid, NULL, 0);
 | 
			
		||||
    if (data_buf == (Data *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        while (data_buf->flag == 0)
 | 
			
		||||
            ;
 | 
			
		||||
        sleep(1);
 | 
			
		||||
        printf("read data: %s\n", data_buf->data);
 | 
			
		||||
        data_buf->flag = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								day5/ftok1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								day5/ftok1.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ipc.h>
 | 
			
		||||
 | 
			
		||||
// ftok()函数用于获取消息队列的键值
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    // 获取消息队列的键值,返回值是一个整数,表示消息队列(IPC)的键值
 | 
			
		||||
    key_t key = ftok("/", 26);
 | 
			
		||||
    printf("key = %d\n", key);
 | 
			
		||||
 | 
			
		||||
    // ftok()函数的第一个参数是路径,第二个参数是索引值
 | 
			
		||||
    // 索引值是一个整数,范围是0~255,用于区分不同的消息队列
 | 
			
		||||
    // 超过255的索引值会被截断,例如256会被截断为0,257会被截断为1,相当于循环使用
 | 
			
		||||
    key_t key2 = ftok("/", 26);
 | 
			
		||||
    printf("key = %d\n", key2);
 | 
			
		||||
 | 
			
		||||
    int mask = 0xff; // 0b11111111 低8位掩码
 | 
			
		||||
    printf("mask = %d\n", mask);
 | 
			
		||||
    // 低8位掩码与key进行与运算,得到低8位
 | 
			
		||||
    printf("key & mask = %d\n", key & mask);   // 用于获取低8位
 | 
			
		||||
    printf("key2 & mask = %d\n", key2 & mask); // 用于获取低8位
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										31
									
								
								day5/msgque1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								day5/msgque1.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h> // 系统数据类型定义
 | 
			
		||||
#include <sys/ipc.h>   // IPC相关头文件
 | 
			
		||||
#include <sys/msg.h>   // 消息队列相关头文件
 | 
			
		||||
 | 
			
		||||
// msgget 函数用于创建消息队列,参数1是键值,参数2是权限
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/home/flykhan/", 200); // 获取消息队列的键值
 | 
			
		||||
    printf("key = %d\n", key);
 | 
			
		||||
    if (key == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("ftok");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // msgget 函数用于创建消息队列,参数1是键值,参数2是权限
 | 
			
		||||
    // 返回值是消息队列的标识符,类似于文件描述符
 | 
			
		||||
    // IPC_CREAT 表示如果消息队列不存在则创建,如果存在则打开
 | 
			
		||||
    // 0644 表示权限,类似于文件权限,表示所有者可读写,其他人只读
 | 
			
		||||
    int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列
 | 
			
		||||
    if (msgqid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // msgqid 只要不是 -1 就表示创建成功
 | 
			
		||||
    printf("msgqid = %d\n", msgqid); // 打印消息队列标识符
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								day5/msgque4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								day5/msgque4.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,102 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h> // 系统数据类型定义
 | 
			
		||||
#include <sys/ipc.h>   // IPC相关头文件
 | 
			
		||||
#include <sys/msg.h>   // 消息队列相关头文件
 | 
			
		||||
#include <string.h>    // 字符串操作
 | 
			
		||||
#include <stdlib.h>    // atol 函数
 | 
			
		||||
#include <time.h>      // 时间函数
 | 
			
		||||
#include <unistd.h>    // 头文件含义:unix standard,即unix标准的意思
 | 
			
		||||
 | 
			
		||||
// 消息结构体
 | 
			
		||||
typedef struct msg_
 | 
			
		||||
{
 | 
			
		||||
    long mType;        // 消息类型,必须是 long ,必须在第一个位置
 | 
			
		||||
    char content[100]; // 消息内容,需要小于消息队列的限制值(8192)
 | 
			
		||||
    char title[32];    // 消息标题
 | 
			
		||||
 | 
			
		||||
} MSG;
 | 
			
		||||
 | 
			
		||||
// msgget 函数用于创建消息队列,参数1是键值,参数2是权限
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 200); // 获取消息队列的键值
 | 
			
		||||
 | 
			
		||||
    int msgqid = msgget(key, IPC_CREAT | 0666); // 创建消息队列
 | 
			
		||||
    if (msgqid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 查看 msgqid 消息队列的信息
 | 
			
		||||
    struct msqid_ds msginfo;                      // 消息队列信息结构体
 | 
			
		||||
    int ret = msgctl(msgqid, IPC_STAT, &msginfo); // 获取消息队列信息
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    time_t st = msginfo.msg_stime; // 最后发送消息的时间
 | 
			
		||||
    time_t rt = msginfo.msg_rtime; // 最后接收消息的时间
 | 
			
		||||
    time_t ct = msginfo.msg_ctime; // 最后变更消息的时间
 | 
			
		||||
 | 
			
		||||
    struct tm *stm = localtime(&st); // 转换为北京时间
 | 
			
		||||
    struct tm *rtm = localtime(&rt); // 转换为北京时间
 | 
			
		||||
    struct tm *ctm = gmtime(&ct);    // 转换为北京时间
 | 
			
		||||
 | 
			
		||||
    // // 手动转换为北京时间
 | 
			
		||||
    // st += 8 * 60 * 60;
 | 
			
		||||
    // rt += 8 * 60 * 60;
 | 
			
		||||
    // ct += 8 * 60 * 60;
 | 
			
		||||
    // // 把时间戳转换为字符串
 | 
			
		||||
    // char stime[32] = "";
 | 
			
		||||
    // char rtime[32] = "";
 | 
			
		||||
    // char ctime[32] = "";
 | 
			
		||||
    // ctime_r(&st, stime);
 | 
			
		||||
    // ctime_r(&rt, rtime);
 | 
			
		||||
    // ctime_r(&ct, ctime);
 | 
			
		||||
    // // 打印时间
 | 
			
		||||
    // printf("最后发送消息的时间: %s", stime);
 | 
			
		||||
    // printf("最后接收消息的时间: %s", rtime);
 | 
			
		||||
    // printf("最后变更消息的时间: %s", ctime);
 | 
			
		||||
    // printf("最后变更消息的时间: %s", ctime);
 | 
			
		||||
 | 
			
		||||
    // + 1900 是因为 struct tm 结构体中的 tm_year 字段表示的是从1900年开始的年数的偏移量。
 | 
			
		||||
    // +1 是因为 struct tm 结构体中的 tm_mon 字段表示的是月份的偏移量,范围是0-11,其中0表示一月,11表示十二月
 | 
			
		||||
    printf("最后发送消息的时间: %d-%d-%d %d:%d:%d\n", stm->tm_year + 1900, stm->tm_mon + 1, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec);
 | 
			
		||||
    printf("最后接收消息的时间: %d-%d-%d %d:%d:%d\n", rtm->tm_year + 1900, rtm->tm_mon + 1, rtm->tm_mday, rtm->tm_hour, rtm->tm_min, rtm->tm_sec);
 | 
			
		||||
    printf("最后变更消息的时间: %d-%d-%d %d:%d:%d\n", ctm->tm_year + 1900, ctm->tm_mon + 1, ctm->tm_mday, ctm->tm_hour, ctm->tm_min, ctm->tm_sec);
 | 
			
		||||
 | 
			
		||||
    // 打印消息队列的信息
 | 
			
		||||
    printf("\n消息队列的信息:\n");
 | 
			
		||||
    printf("消息队列的标识符: %d\n", msginfo.msg_perm.__key);
 | 
			
		||||
    printf("消息队列的权限: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
 | 
			
		||||
 | 
			
		||||
    // 修改消息队列的权限
 | 
			
		||||
    // msginfo.msg_perm.mode = 0644; // 修改权限
 | 
			
		||||
    msginfo.msg_perm.mode |= 0111; // 修改权限,增加可执行权限
 | 
			
		||||
    ret = msgctl(msgqid, IPC_SET, &msginfo);
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
 | 
			
		||||
 | 
			
		||||
    // execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
 | 
			
		||||
 | 
			
		||||
    // 减少权限
 | 
			
		||||
    msginfo.msg_perm.mode &= ~0101; // 修改权限,减少可执行权限
 | 
			
		||||
    ret = msgctl(msgqid, IPC_SET, &msginfo);
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("修改消息队列的权限为: %04o\n", msginfo.msg_perm.mode); // %04o 是八进制输出,占4位,不足4位前面补0
 | 
			
		||||
 | 
			
		||||
    execlp("ipcs", "ipcs", "-q", NULL); // 打印消息队列
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										29
									
								
								day5/msgque_msgctl_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								day5/msgque_msgctl_test.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/ipc.h>
 | 
			
		||||
#include <sys/msg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
// 测试 msgctl ,用于删除消息队列
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 65);                 // 使用ftok函数生成一个唯一的键值
 | 
			
		||||
    int msqid = msgget(key, 0666 | IPC_CREAT); // 创建或获取消息队列
 | 
			
		||||
 | 
			
		||||
    if (msqid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgget");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 控制操作:删除消息队列
 | 
			
		||||
    if (msgctl(msqid, IPC_RMID, NULL) == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("msgctl");
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Message queue removed successfully.\n");
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								day5/producer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								day5/producer.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
// 生产者
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
typedef struct data
 | 
			
		||||
{
 | 
			
		||||
    char data[32];
 | 
			
		||||
    int flag;
 | 
			
		||||
} Data;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    printf("producer\n");
 | 
			
		||||
 | 
			
		||||
    key_t key = ftok("/", 15);
 | 
			
		||||
    if (key == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("ftok");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    Data *data_buf = (Data *)shmat(shmid, NULL, 0);
 | 
			
		||||
    if (data_buf == (Data *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    int num = 0;
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        while (data_buf->flag == 1)
 | 
			
		||||
            ;
 | 
			
		||||
        sprintf(data_buf->data, "hello, %d", num++);
 | 
			
		||||
        data_buf->flag = 1;
 | 
			
		||||
        printf("write data: %s\n", data_buf->data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								day5/shm1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								day5/shm1.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
// 共享内存
 | 
			
		||||
/*
 | 
			
		||||
是的,"shm"是共享内存(shared memory)的缩写,它通常用于表示共享内存相关的概念和操作。共享内存是一种进程间通信的机制,允许多个进程共享同一块内存区域,从而实现高效的数据交换和共享。
 | 
			
		||||
 | 
			
		||||
在Linux系统中,使用`shmget`函数创建或获取共享内存段(shared memory segment),进程可以通过该段共享内存进行通信。共享内存段是一个连续的内存区域,可以被多个进程映射到各自的地址空间中,从而实现共享数据的读写。
 | 
			
		||||
 | 
			
		||||
共享内存在进程间通信中具有高速和低开销的优势,因为进程可以直接读写共享内存,而无需进行复制或传输数据。但同时也需要注意正确地处理同步和互斥,以避免数据竞争和一致性问题。
 | 
			
		||||
 | 
			
		||||
因此,当你看到"shm"时,通常指的是共享内存,而"share mem"是它的完整表达形式。这两个术语可以互换使用,表示同一概念。
 | 
			
		||||
*/
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的标识
 | 
			
		||||
    int shmid = shmget(key, 32, IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("shmid=%d\n", shmid);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										44
									
								
								day5/shm2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								day5/shm2.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,44 @@
 | 
			
		||||
// 共享内存
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// 共享内存写数据
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的标识
 | 
			
		||||
    int shmid = shmget(key, 32, IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("shmid=%d\n", shmid);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的首地址
 | 
			
		||||
    char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
 | 
			
		||||
    if (buf == (char *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    strcpy(buf, "hi, shared memory");
 | 
			
		||||
    printf("write data ok\n");
 | 
			
		||||
 | 
			
		||||
    /*  
 | 
			
		||||
    // 删除共享内存
 | 
			
		||||
    int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("shared memory deleted\n");
 | 
			
		||||
    */
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								day5/shm3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								day5/shm3.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// 共享内存
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// 共享内存读数据
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的标识
 | 
			
		||||
    int shmid = shmget(key, 32, IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("shmid=%d\n", shmid);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的首地址
 | 
			
		||||
    char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
 | 
			
		||||
    if (buf == (char *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("共享内存的数据:%s\n", buf);
 | 
			
		||||
    /* 
 | 
			
		||||
    // 删除共享内存
 | 
			
		||||
    int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("shared memory deleted\n");
 | 
			
		||||
 */
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								day5/shm4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								day5/shm4.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
// 共享内存
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// 解除映射
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的标识
 | 
			
		||||
    int shmid = shmget(key, 32, IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("shmid=%d\n", shmid);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的首地址
 | 
			
		||||
    char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
 | 
			
		||||
    if (buf == (char *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("共享内存的数据:%s\n", buf);
 | 
			
		||||
 | 
			
		||||
    // 解除映射
 | 
			
		||||
    int ret = shmdt(buf);
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmdt");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("解除映射成功 ok\n");
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								day5/shm5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								day5/shm5.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
// 共享内存
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// 共享内存删除
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的标识
 | 
			
		||||
    int shmid = shmget(key, 32, IPC_CREAT | 0666);
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("shmid=%d\n", shmid);
 | 
			
		||||
 | 
			
		||||
    // 获取共享内存的首地址
 | 
			
		||||
    char *buf = shmat(shmid, NULL, 0); // NULL表示让系统自动分配共享内存的首地址
 | 
			
		||||
    if (buf == (char *)-1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmat");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("共享内存的数据:%s\n", buf);
 | 
			
		||||
 | 
			
		||||
    // 删除共享内存
 | 
			
		||||
    // NULL 表示不关心共享内存的信息
 | 
			
		||||
    // int ret = shmctl(shmid, IPC_RMID, NULL); // 删除共享内存
 | 
			
		||||
 | 
			
		||||
    // 如果不写 NULL,应该写一个结构体,表示共享内存的信息
 | 
			
		||||
    struct shmid_ds ds;
 | 
			
		||||
    int ret = shmctl(shmid, IPC_RMID, &ds); // 删除共享内存
 | 
			
		||||
    if (ret == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
    printf("shared memory deleted\n");
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										109
									
								
								day5/shm6.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								day5/shm6.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,109 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/shm.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
typedef struct data
 | 
			
		||||
{
 | 
			
		||||
    int data;
 | 
			
		||||
    int flag;
 | 
			
		||||
} Data;
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    key_t key = ftok("/", 28);
 | 
			
		||||
    int shmid = shmget(key, sizeof(Data), IPC_CREAT | 0666);
 | 
			
		||||
 | 
			
		||||
    if (shmid == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmget");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fork() == 0) // 生产者进程
 | 
			
		||||
    {
 | 
			
		||||
        Data *data = shmat(shmid, NULL, 0);
 | 
			
		||||
        if (data == (Data *)-1)
 | 
			
		||||
        {
 | 
			
		||||
            perror("shmat");
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data->flag = 0; // 初始化为 0
 | 
			
		||||
        data->data = 0; // 初始化为 0
 | 
			
		||||
        for (int i = 0; i < 100; i++)
 | 
			
		||||
        {
 | 
			
		||||
            // 等待消费者消费数据
 | 
			
		||||
            while (data->flag == 1)
 | 
			
		||||
                ;
 | 
			
		||||
            data->data++; // 生产数据
 | 
			
		||||
            data->flag = 1;
 | 
			
		||||
            printf("生产者生产数据:%d\n", data->data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 解除映射
 | 
			
		||||
        if (shmdt(data) == -1)
 | 
			
		||||
        {
 | 
			
		||||
            perror("shmdt");
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        _exit(0); // 子进程退出
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (fork() == 0) // 消费者进程
 | 
			
		||||
    {
 | 
			
		||||
        Data *data = shmat(shmid, NULL, 0);
 | 
			
		||||
        if (data == (Data *)-1)
 | 
			
		||||
        {
 | 
			
		||||
            perror("shmat");
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        data->flag = 0; // 初始化为 0
 | 
			
		||||
        data->data = 0; // 初始化为 0
 | 
			
		||||
        for (int i = 0; i < 100; i++)
 | 
			
		||||
        {
 | 
			
		||||
            // 等待生产者生产数据
 | 
			
		||||
            while (data->flag == 0)
 | 
			
		||||
            {
 | 
			
		||||
                printf("等待生产者生产数据\n");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            printf("消费者消费数据:%d\n", data->data);
 | 
			
		||||
            // 消费到 100 时退出
 | 
			
		||||
            if (data->data == 10)
 | 
			
		||||
                break;
 | 
			
		||||
            sleep(1);
 | 
			
		||||
            data->flag = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 解除映射
 | 
			
		||||
        if (shmdt(data) == -1)
 | 
			
		||||
        {
 | 
			
		||||
            perror("shmdt");
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
        _exit(0); // 子进程退出
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (1)
 | 
			
		||||
    {
 | 
			
		||||
        // WUNTRACED 不跟踪 ?
 | 
			
		||||
        int pid = waitpid(0, NULL, WUNTRACED);
 | 
			
		||||
        if (pid == -1)
 | 
			
		||||
        {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        printf("%d 子进程结束\n", pid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 删除共享内存
 | 
			
		||||
    if (shmctl(shmid, IPC_RMID, NULL) == -1)
 | 
			
		||||
    {
 | 
			
		||||
        perror("shmctl");
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user