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的集合࿰…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
机器学习的数学基础:线性模型
线性模型 线性模型的基本形式为: f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法,得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__ is not explicitly defined.
这个警告表明您在使用Vue的esm-bundler构建版本时,未明确定义编译时特性标志。以下是详细解释和解决方案: 问题原因: 该标志是Vue 3.4引入的编译时特性标志,用于控制生产环境下SSR水合不匹配错误的详细报告1使用esm-bundler…...