SDL事件处理以及线程使用(2)
事件使用
#include <stdio.h>
#include <SDL.h>#define FF_QUIT_EVENT (SDL_USEREVENT + 1) // 定义自定义事件#undef main
int main()
{SDL_Window* pWindow = NULL;SDL_Init(SDL_INIT_VIDEO);// 创建窗口pWindow = SDL_CreateWindow("Event Test Title",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,640,480,SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);if(NULL == pWindow){printf("Create window error: %s\n", SDL_GetError());return -1;}SDL_Event event;int is_exit = 1;while(is_exit){SDL_WaitEvent(&event);switch (event.type) // 区分鼠标事件、键盘事件{case SDL_KEYDOWN: // 键盘按下事件switch (event.key.keysym.sym){case SDLK_a:break;case SDLK_s:break;case SDLK_d:break;case SDLK_w:break;case SDLK_q:{SDL_Event myEvent; // 自定义事件并发送myEvent.type = FF_QUIT_EVENT;SDL_PushEvent(&myEvent);break;}}break;case SDL_MOUSEBUTTONDOWN: // 鼠标按键按下事件switch(event.button.button){case SDL_BUTTON_LEFT:printf("mouse button left down\n");break;case SDL_BUTTON_RIGHT:printf("mouse button right down\n");break;}break;case SDL_MOUSEMOTION: // 鼠标移动事件printf("mouse move {%d, %d}\n", event.button.x, event.button.y);break;case FF_QUIT_EVENT: // 自定义事件printf("myself event is triggered\n");is_exit = 0;break;}}// 销毁窗口,释放资源if(pWindow)SDL_DestroyWindow(pWindow);SDL_Quit();return 0;
}
线程使用
#include <SDL.h>
#include <stdio.h>int n = 0;
// 线程处理函数
int thread_work(void* arg)
{printf("enter thread arg: %d\n", *((int*)arg));for(int i = 0; i < 500000; i++){n++;}return 0;
}#undef main
int main()
{int thread_num = 520;// 创建线程SDL_Thread* thread1 = SDL_CreateThread(thread_work, "thread1Name", &thread_num);if(NULL == thread1){printf("thread1 create error %s\n", SDL_GetError());return -1;}thread_num++;SDL_Thread* thread2 = SDL_CreateThread(thread_work, "thread2Name", &thread_num);if(NULL == thread2){printf("thread2 create error: %s\n", SDL_GetError());return -1;}// 等待线程汇入主线程SDL_WaitThread(thread1, NULL);SDL_WaitThread(thread2, NULL);printf("n is value: %d\n", n);return 0;
}

互斥锁使用
#include <SDL.h>
#include <stdio.h>/// 互斥锁 ///
SDL_mutex* mutex = NULL;
/int n = 0;
// 线程处理函数
int thread_work(void* arg)
{printf("enter thread arg: %d\n", *((int*)arg));/// 上锁 ///SDL_LockMutex(mutex);/for(int i = 0; i < 500000; i++){n++;}/// 解锁 ///SDL_UnlockMutex(mutex);/return 0;
}#undef main
int main()
{/// 创建互斥锁 ///mutex = SDL_CreateMutex();if(NULL == mutex){printf("Create mutex error: %s\n", SDL_GetError());return -1;}/int thread_num = 520;// 创建线程SDL_Thread* thread1 = SDL_CreateThread(thread_work, "thread1Name", &thread_num);if(NULL == thread1){printf("thread1 create error %s\n", SDL_GetError());return -1;}thread_num++;SDL_Thread* thread2 = SDL_CreateThread(thread_work, "thread2Name", &thread_num);if(NULL == thread2){printf("thread2 create error: %s\n", SDL_GetError());return -1;}// 等待线程汇入主线程SDL_WaitThread(thread1, NULL);SDL_WaitThread(thread2, NULL);printf("n is value: %d\n", n);/// 释放锁资源 ///SDL_DestroyMutex(mutex);/return 0;
}

条件变量使用
#include <SDL.h>
#include <stdio.h>SDL_mutex* g_mutex = NULL; // 互斥锁
SDL_cond* g_cond = NULL; // 条件变量// 线程等待函数
int thread_waitFunc(void* arg)
{printf("thread %d wait......\n", *(int*)arg);SDL_LockMutex(g_mutex);SDL_CondWait(g_cond, g_mutex);SDL_UnlockMutex(g_mutex);printf("thread wait end, start work......\n");return 1;
}// 线程发送信号函数
int thread_signFunc(void* arg)
{printf("thread %d sleep 5s\n", *(int*)arg);sleep(5); // 5秒后唤醒等待的线程SDL_CondSignal(g_cond); // 唤醒等待的线程printf("thread %d send signal success\n", *(int*)arg);return 666;
}#undef main
int main()
{// 创建互斥锁和条件变量g_mutex = SDL_CreateMutex();g_cond = SDL_CreateCond();if(g_mutex == NULL || g_cond == NULL){printf("Create mutex or cond failed: %s\n", SDL_GetError());return -1;}// 创建线程int wait_num = 1001;SDL_Thread* thread_wait = SDL_CreateThread(thread_waitFunc, "threadWait", &wait_num);if(NULL == thread_wait){printf("create threadWait error: %s\n", SDL_GetError());return -1;}wait_num++;SDL_Thread* thread_sign = SDL_CreateThread(thread_signFunc, "threadSignal", &wait_num);if(NULL == thread_sign){printf("create threadSign error: %s\n", SDL_GetError());SDL_CondSignal(g_cond);SDL_WaitThread(thread_wait, NULL);return -1;}// 将两个线程汇入主线程SDL_WaitThread(thread_wait, NULL);SDL_WaitThread(thread_sign, NULL);// 释放锁跟条件变量的资源SDL_DestroyMutex(g_mutex);SDL_DestroyCond(g_cond);return 0;
}

相关文章:
SDL事件处理以及线程使用(2)
事件使用 #include <stdio.h> #include <SDL.h>#define FF_QUIT_EVENT (SDL_USEREVENT 1) // 定义自定义事件#undef main int main() {SDL_Window* pWindow NULL;SDL_Init(SDL_INIT_VIDEO);// 创建窗口pWindow SDL_CreateWindow("Event Test Title&…...
DAY38 动态规划 + 509. 斐波那契数 + 70. 爬楼梯 + 746. 使用最小花费爬楼梯
动态规划理论 动态规划,Dynamic Programming, DP, 如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导…...
Redis快速上手篇七(集群-一台虚拟机六个节点)
http://t.csdnimg.cn/S0NpK与上篇六个虚拟机配置基本一样有不懂可以看上篇配置实例 集群搭建 根据上篇文章,本篇只着重于小方面的配置差别 配置集群一般不要设置密码 1.搭建一台虚拟机后再安装目录下新建文件夹 redis_cluster 2.在文件夹内创建六个文…...
社恐了怎么办?如何改变社交恐惧症?
社恐这个词已经算是普及了,自嘲自己是社恐的人真的挺多的,好像一句我社恐了就能解析很多问题,其实真正的社恐远比我们想象的要痛苦多了,社恐能被更多人认识到本来是件好事,但是过于的用社恐来给自己贴标签,…...
HiQPdf Library for .NET - HTML to PDF Crack
HiQPdf Library for .NET - HTML 到 PDF 转换器 .NET Core,用于 .NET 的 HiQPdf HTML 到 PDF 转换器 :HiQPdf HTML to PDF Library for .NET C# 和 HTML to PDF .NET Core 为您提供了一个现代、快速、灵活且强大的工具,只需几行代码即可创建复…...
ES6中Set集合
ES6中的Set是一种数据结构,类似于数组,但是它的值都是唯一的。它是通过一组有序的、由唯一元素组成的集合实现的,不允许重复项。Set可以用于存储任何类型的数据,包括原始类型和复合类型,如对象和数组。 Set有以下特点…...
论坛介绍 | COSCon'23 开源文化(GL)
众多开源爱好者翘首期盼的开源盛会:第八届中国开源年会(COSCon23)将于 10月28-29日在四川成都市高新区菁蓉汇举办。本次大会的主题是:“开源:川流不息、山海相映”!各位新老朋友们,欢迎到成都&a…...
【httpd】 Apache http服务器目录显示不全解决
文章目录 1. 文件名过长问题1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex.conf1.2 在配置文件httpd-autoindex.conf中的修改:1.3 修改完成后重启Apache: 1. 文件名过长问题 1.1 在centos中文件所谓位置etc/httpd/conf.d/httpd-autoindex…...
笔记本电脑搜索不到wifi6 无线路由器信号
路由器更换成wifi6 无线路由器后,手机能搜索到这个无线信号,但是笔记本搜索不到这个无线信号,后网上搜索后发现是无线网卡驱动问题,很多无线网卡使用的是Intel芯片,Intel就此发布了公告,升级驱动就可以彻底…...
js获取input?
在JavaScript中,获取输入框(通常指的是HTML的<input>元素)的值有多种方法。以下是其中的一些: 通过ID获取: javascriptvar inputValue document.getElementById(inputId).value; 这里,inputId 是…...
STM32 CAN使用
STM32 CAN使用 简介各种通讯接口对比报文总线上的报文信息表示为几种固定的赖类型数据帧列表模式掩码模式配置CAN配置参数位时序 简介 控制器局域网CAN(Controller Area Network)是由德国博世公司为汽车应用而开发的多主机局部网络,用于汽车的监测和控制…...
安全和便捷:如何将运营商二要素API应用于实名制管理中
引言 随着互联网的快速发展,数字化身份验证和实名制管理变得越来越重要。在金融、电子商务、社交媒体等领域,确保用户身份的安全和准确性至关重要。运营商二要素核验API成为了实名制管理的有力工具,它不仅能够提供高水平的安全性,…...
leetcode-二叉树
B树和B树的区别 B树,也即balance树,是一棵多路自平衡的搜索树。它类似普通的平衡二叉树,不同的一点是B树允许每个节点有更多的子节点。 B树内节点不存储数据,所有关键字都存储在叶子节点上。B树: B树: 二叉…...
【鸿蒙软件开发】ArkTS基础组件之TextTimer(文本显示计时)、TimePicker(时间选择)
文章目录 前言一、TextTimer1.1 子组件1.2 接口参数TextTimerController 1.3 属性1.4 事件1.5 示例代码 二、TimePicker2.1 子组件2.2 接口参数 2.3 属性2.4 事件TimePickerResult对象说明 2.5 示例代码 总结 前言 通过文本显示计时信息并控制其计时器状态的组件。 时间选择组…...
pytorch 笔记:KLDivLoss
1 介绍 对于具有相同形状的张量 ypred 和 ytrue(ypred 是输入,ytrue 是目标),定义逐点KL散度为: 为了在计算时避免下溢问题,此KLDivLoss期望输入在对数空间中。如果log_targetTrue,则目标…...
父子项目打包发布至私仓库
父子项目打包发布至私仓库 1、方法一 在不需要发布至私仓的模块上添加如下代码: <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><configuration><skip>true</s…...
汽车网络安全--ECU的安全更新
目前,汽车ECU的软件更新可以总结分成三大类: 工厂刷写模式:工厂大批量刷写或者升级,一般在出厂用; 工程模式:4S店、工厂等专业人员进行的ECU固件更新,通常是动力、转向、车控等; 车主模式:车主根据云端推送信息,通过IVI进行应用软件更新;目前也有趋势通过这种方式刷…...
NLP之搭建RNN神经网络
文章目录 代码展示代码意图代码解读知识点介绍1. Embedding2. SimpleRNN3. Dense 代码展示 # 构建RNN神经网络 from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, SimpleRNN, Embedding import tensorflow as tfrnn Sequential() …...
Android问题笔记四十三:JNI 开发如何快速定位崩溃问题
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...
机器学习 | 决策树算法
一、决策树算法概述 1、树模型 决策树:从根节点开始一步步走到叶子节点(决策)。所有的数据最终都会落到叶子节点,既可以做分类也可以做回归。 在分类问题中,表示基于特征对实例进行分类的过程,可以认为是if-then的集合࿰…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...

