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的集合࿰…...

wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...