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的集合࿰…...
深入解析Ollama-for-amd:AMD GPU本地大模型部署实战指南
深入解析Ollama-for-amd:AMD GPU本地大模型部署实战指南 【免费下载链接】ollama-for-amd Get up and running with Llama 3, Mistral, Gemma, and other large language models.by adding more amd gpu support. 项目地址: https://gitcode.com/gh_mirrors/ol/ol…...
jor1k性能优化技巧:如何显著提升浏览器中Linux的运行速度
jor1k性能优化技巧:如何显著提升浏览器中Linux的运行速度 【免费下载链接】jor1k Online OR1K Emulator running Linux 项目地址: https://gitcode.com/gh_mirrors/jo/jor1k jor1k是一款能够在浏览器中运行Linux的在线OR1K模拟器,让用户无需本地安…...
Obsidian Local REST API:解锁个人知识库的自动化编程接口
Obsidian Local REST API:解锁个人知识库的自动化编程接口 【免费下载链接】obsidian-local-rest-api A secure REST API and Model Context Protocol (MCP) server for your vault. 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-local-rest-api 你…...
MulimgViewer 终极指南:高效图片对比与拼接的完整解决方案
MulimgViewer 终极指南:高效图片对比与拼接的完整解决方案 【免费下载链接】MulimgViewer MulimgViewer is a multi-image viewer that can open multiple images in one interface, which is convenient for image comparison and image stitching. 项目地址: ht…...
别再新建空文件了!手把手教你用CodeBlocks创建可调试的C/C++工程(避坑中文路径)
别再新建空文件了!手把手教你用CodeBlocks创建可调试的C/C工程(避坑中文路径) 刚接触编程的新手常常会遇到这样的困惑:明明按照教程写好了代码,设置了断点,按下F7却毫无反应。这种挫败感往往源于一个被多数…...
C++Stack栈类模版实例详解
栈的实现方式分为3种基于静态数组实现,内部预设一个很大的数组对象, 实现简单,缺点是空间受限。基于动态数组实现,内部预设一个容量值,然后分配一段内存空间数组,如果入栈大于默认容量值时,则再次扩大分配新的内存数组,并将旧数组拷贝至新数组及释放旧数组.基于双向…...
【紧急更新】Midjourney 6.2已悄悄禁用glass关键词!替代方案+3套可直接复用的prompt模板(限24小时公开)
更多请点击: https://intelliparadigm.com 第一章:Midjourney 6.2玻璃质感禁用事件全貌解析 2024年7月,Midjourney官方悄然更新至v6.2版本,并在未发布正式公告的情况下,对部分高精度材质描述词实施了隐性限制——其中…...
ARMv8内存访问指令STLUR与STLXP详解
1. ARMv8内存访问指令概述 在ARMv8架构中,内存访问指令构成了处理器与内存系统交互的基础设施。作为RISC架构的典型代表,ARMv8通过精简但功能明确的指令集实现了高效的内存操作。其中存储(Store)类指令负责将寄存器数据写入内存,而根据不同的…...
抖音批量下载器终极指南:免费高效的视频采集解决方案
抖音批量下载器终极指南:免费高效的视频采集解决方案 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback suppor…...
技术从业者的面试技巧:如何通过大厂的技术面试
在软件行业的招聘生态中,大厂的技术面试如同一场严苛的专业试炼,尤其对于软件测试从业者而言,不仅要展现扎实的技术功底,更要体现出符合大厂标准的工程思维与问题解决能力。想要在竞争激烈的面试中脱颖而出,需要从面试…...

