欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > opencv 打开图片后,cv::mat存入共享内存的代码,如何设置队列?

opencv 打开图片后,cv::mat存入共享内存的代码,如何设置队列?

2024/10/24 11:14:04 来源:https://blog.csdn.net/djfjkj52/article/details/139806993  浏览:    关键词:opencv 打开图片后,cv::mat存入共享内存的代码,如何设置队列?

参考

https://blog.csdn.net/BrilliantAntonio/article/details/120606129

分析

  • 执行Add操作时,随机产生一个大写英文字母模拟产品,放入缓冲区,同时调整队尾指针end.
  • 执行Remove操作时,将当前缓冲区资源清空,同时调整队首指针start.
#define SEMKEY 123
#define SHMKEY 456
#define BUFNUM 10
#define SEMNUM 3/// main /
struct Buffer
{int start, end;char buffer[BUFNUM];
};void Add(struct Buffer *shm)
{char product = 'A' + rand() % 26;printf("producer %d: added product %c into buffer:\t", getpid(), product);shm -> buffer [shm -> end] = product;shm -> end = (shm -> end + 1) % BUFNUM;printf("|%s|\n", shm -> buffer);
}void Remove(struct Buffer *shm)
{char product = shm -> buffer [shm -> start];printf("consumer %d: removed product %c from buffer:\t", getpid(), product);shm -> buffer [shm -> start] = ' ';shm -> start = (shm -> start + 1) % BUFNUM;printf("|%s|\n", shm -> buffer);
}

这两个函数 AddRemove 是模拟生产者-消费者问题中的两个基本操作:一个用于向缓冲区添加产品(或数据),另一个用于从缓冲区移除产品。这两个函数都操作一个共享内存(shm),该共享内存应该包含一个缓冲区以及两个索引(startend)来跟踪缓冲区的哪一部分是空的或满的。

下面是对这两个函数的详细解释:

Add 函数

  1. 生成随机产品char product = 'A' + rand() % 26; 这行代码生成一个随机的大写字母(从 ‘A’ 到 ‘Z’)作为模拟的“产品”。
  2. 打印添加操作:使用 printf 打印出生产者进程ID和添加的产品。
  3. 向缓冲区添加产品shm -> buffer [shm -> end] = product; 这行代码将随机生成的产品放入缓冲区的当前结束位置。
  4. 更新结束索引shm -> end = (shm -> end + 1) % BUFNUM; 这行代码更新结束索引以指向下一个空位置。如果 end 已经到达缓冲区的末尾,它会被重置为缓冲区的开始位置(实现循环缓冲区)。
  5. 打印缓冲区内容:最后,printf 打印出整个缓冲区的内容。但这里有一个潜在的问题:缓冲区 shm -> buffer 被当作字符串处理,但缓冲区中可能包含非打印字符(如空格或其他非ASCII字符),这可能导致输出看起来不是预期的那样。

Remove 函数

  1. 获取产品char product = shm -> buffer [shm -> start]; 这行代码从缓冲区的当前开始位置获取产品。
  2. 打印移除操作:使用 printf 打印出消费者进程ID和移除的产品。
  3. 清空开始位置shm -> buffer [shm -> start] = ' '; 这行代码将开始位置的内容设置为空格(或其他非产品字符)。这用于表示该位置现在是空的。
  4. 更新开始索引shm -> start = (shm -> start + 1) % BUFNUM; 这行代码更新开始索引以指向下一个有产品的位置。如果 start 已经到达缓冲区的末尾,它会被重置为缓冲区的开始位置(实现循环缓冲区)。
  5. 打印缓冲区内容:同样,这里打印出整个缓冲区的内容,但可能存在与 Add 函数相同的问题。

注意事项

  • 缓冲区大小BUFNUM 应该是在其他地方定义的一个常量,表示缓冲区的大小。

初始化

    void *temp = NULL;struct Buffer *shm = NULL;temp = shmat(shmId, 0, 0);if(temp == (void *) -1){printf("share memory attachment failed!\n");exit(EXIT_FAILURE);        }shm = (struct Buffer *) temp;shm -> start = 0;shm -> end = 0;for(i = 0; i < BUFNUM; i++){shm -> buffer[i] = ' ';}

使用

第一个信号量为empty,表示缓冲池为空的个数;
第二个信号量为full,表示缓冲池中的产品个数;
第三个信号量为mutex,控制对缓冲池的读取权限。

使用时,

生产者依次刷新 empty(-1)->mutex(-1)->mutex(+1)->full(+1)
消费者依次刷新 full(-1)->mutex(-1)->mutex(+1)->empty(+1)

void Producer(int semId, struct Buffer *shm)
{do{// wait empty region...// wait mutex...Add(shm);// signal mutex...// singal full region...sleep(random() % 2);}while(1);
}void Consumer(int semId, struct Buffer *shm)
{do{// wait full region...// wait mutex...Remove(shm);// signal mutex...// singal empty region......}while(1);
}

总结

这个循环的缓冲器好像也能实现我们的需求

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com