Qt中槽函数在那个线程执行的探索和思考
信号和槽是Qt的核心机制之一,通过该机制大大简化了开发者的开发难度。信号和槽属于观察者模式(本质上是回调函数的应用)。是函数就需要考虑其是在那个线程中执行,本文讨论的就是槽函数在那个线程中执行的问题。
目录
1. connect函数的第五个参数说明
2. 发送者和接收者在同一个线程创建
2.1 槽函数在发送者所在线程执行
2.3 槽函数不在发送者所在线程执行
3. 发送者和接收者在不同线程创建
3.1 槽函数在接收者所在线程执行
3.2 槽函数在发送者所在线程执行
4.发送者所在线程和发送信号线程的区别
1. connect函数的第五个参数说明
connect函数用来连接信号和槽,类似于提前注册。其第五个参数默认是Qt::AutoConnection,所以开发者很多时候可以忽略此参数。但是在牵扯到复杂业务开发,尤其是多线程并发开发时往往需要关注第五个参数,第五个参数取值和含义如下:
- Qt::AutoConnection
自动连接,发送者和接受者在同一个线程时等同于Qt::DirectConnection,不同线程等同于Qt::QueuedConnection
- Qt::DirectConnection
直接(同步)连接,槽函数在接受者所依附线程执行。
- Qt::QueuedConnection
队列(异步)连接,槽函数在发送信号的线程执行。异步连接的时候,信号是由接收者所在的线程的事件处理机制来处理的,如果接收者所在的线程没有事件处理的话,这个信号就不会被处理
- Qt::BlockingQueuedConnection
阻塞连接,发送者和接收者在同一线程时会死锁
- Qt::UniqueConnection
唯一连接,防止信号和槽重复连接
- Qt::SingleShotConnection
单次连接,信号和槽函数只连接一次,槽函数执行后连接会自动断开
2. 发送者和接收者在同一个线程创建
2.1 槽函数在发送者所在线程执行
发送者
sender.h
#ifndef SENDER_H
#define SENDER_H#include <QObject>
#include <QString>class Sender :public QObject {Q_OBJECTpublic:Sender(QObject* parent = 0);public slots :void emitsig(const QString& str, const int& ci);signals:void sig(const QString& str, const int& ci);
};#endif // SENDER_H
sender.cpp
#include "sender.h"
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>Sender::Sender(QObject* parent) : QObject(parent) {}void Sender::emitsig(const QString& str, const int& ci)
{qDebug() << "sender signal thread id is: " << QThread::currentThreadId()<< str << ci;emit sig(str, ci);
}
接收者
recver.h
#ifndef RECVER_H
#define RECVER_H#include <QObject>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>class Recver : public QObject
{Q_OBJECT
public:explicit Recver(QObject *parent = nullptr);public slots :void slot(const QString& str, const int& ci);
};#endif // RECVER_H
recver.cpp
#include "recver.h"
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>Recver::Recver(QObject *parent): QObject{parent}
{}void Recver::slot(const QString& str, const int& ci) {qDebug() << "recver slot thread id is: " << QThread::currentThreadId()<< str << ci;
}
main函数
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>#include "sender.h"
#include "recver.h"
#include "mythread.h"/*
// QObject::connect函数的第五个参数:Qt::AutoConnection:自动连接,发送者和接受者在同一个线程时等同于Qt::DirectConnection,不同线程等同于Qt::QueuedConnectionQt::DirectConnection:直接调用连接,槽函数在接受者所依附线程执行。Qt::QueuedConnection:异步调用连接,槽函数在发送信号的线程执行。异步连接的时候,信号是由接收者所在的线程的事件处理机制来处理的,如果接收者所在的线程没有事件处理的话,这个信号就不会被处理Qt::BlockingQueuedConnection:阻塞连接调用,发送者和接收者在同一线程时会死锁Qt::UniqueConnection:防止信号和槽重复连接Qt::SingleShotConnection:信号和槽函数仅只需单次连接,槽函数执行后连接会自动断开
*//*
// Qt4和Qt5都适用的连接方式,注意:此方式是在Q5上可能会导致槽函数不被调用,此时可尝试使用Qt5新的连接方式
QObject::connect(&sender, SIGNAL(sig()), &recver, SLOT(slot()), Qt::DirectConnection);
QObject::connect(&sender, SIGNAL(sig()), &recver, SLOT(slot()), Qt::QueuedConnection);
//QObject::connect(&sender, SIGNAL(sig()), &recver, SLOT(slot()), Qt::BlockingQueuedConnection);
QObject::connect(&sender, SIGNAL(sig()), &recver, SLOT(slot()), Qt::UniqueConnection);
QObject::connect(&sender, SIGNAL(sig()), &recver, SLOT(slot()), Qt::SingleShotConnection);
*//*
// Qt5最新的连接方式
QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot, Qt::DirectConnection);
QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot, Qt::QueuedConnection);
// 发送者和接收者在同一个线程,将会死锁
//QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot, Qt::BlockingQueuedConnection);
//QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot, Qt::UniqueConnection);
QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot, Qt::SingleShotConnection);
*/// 主线程获取
/*
QCoreApplication::instance()->thread();
*//*
// 关于Qt线程的使用说明
在Qt4.3(包括)之前,run 是虚函数,必须子类化QThread来实现run函数。
而从Qt4.4开始,qthreads-no-longer-abstract,run 默认调用 QThread::exec() 。这样一来不需要子类化 QThread 了,只需要子类化一个 QObject就够了
QThread中run对于线程的作用相当于main函数对于应用程序。它是线程的入口,run的开始和结束意味着线程的开始和结束。
QThread所依附的线程,就是创建线程的线程。
QThread管理的线程,就是run中创建的线程。
*/// 连接多次,发送信号槽函数也会多次触发
void test1() {Sender sender;Recver recver;QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot);QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot);qDebug() << "call first";sender.emitsig("fist", 110);qDebug() << "call second";sender.emitsig("second", 220);qDebug() << "call third";sender.emitsig("third", 330);
}// 接受对象虽然是线程对象,但是槽函数却在发送对象所在线程对象执行,因为接收者依附于发送对象所在线程
/*
QThread中slot和run函数共同操作的对象,都会用QMutex锁住是因为slot和run处于不同线程,需要线程间的同步。
*/
void test2() {Sender sender;Mythread mythread;// Mythread构造函数中去掉moveToThread(this);,槽函数将在主线程执行,加上moveToThread(this)槽函数将在子线程执行// 加上moveToThread(this)后连接方式修改为Qt::DirectConnection,槽函数在主线程中执行QObject::connect(&sender, SIGNAL(sig(const QString&, const int&)), &mythread, SLOT(slot_main(const QString&, const int&)));mythread.start();sender.emitsig("mythread", 440);
}int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "main thead id is : " << QThread::currentThreadId();//std::cout << std::this_thread::get_id() << std::endl;Sender sender;Recver recver;QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot);sender.emitsig("fist", 110);return a.exec();
}
运行效果:
可以看到槽函数在信号发送者所在线程(主线程)中执行。
2.3 槽函数不在发送者所在线程执行
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>#include "sender.h"
#include "recver.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "main thead id is : " << QThread::currentThreadId();//std::cout << std::this_thread::get_id() << std::endl;Sender sender;Recver recver;QObject::connect(&sender, &Sender::sig, &recver, &Recver::slot);QThread thread;recver.moveToThread(&thread);thread.start();sender.emitsig("fist", 110);return a.exec();
}
运行效果:
代码中创建一个子线程对象,并将接收者移动到子线程,槽函数在子线程中执行。
3. 发送者和接收者在不同线程创建
3.1 槽函数在接收者所在线程执行
mythread.h
#ifndef MYTHRED_H
#define MYTHRED_H#include <QThread >class Mythread : public QThread
{
Q_OBJECTpublic:Mythread(QObject* parent = 0);public slots:void slot_main(const QString& str, const int& ci);protected:void run();
};#endif // MYTHRED_H
mythread.cpp
#include "mythread.h"
#include <QDebug>
#include "sender.h"Mythread::Mythread(QObject* parent) : QThread(parent)
{//moveToThread(this);
}void Mythread::slot_main(const QString& str, const int& ci) {qDebug() << "mythread slot_main: " << currentThreadId() << str << ci;
}void Mythread::run() {qDebug() << "mythread thread: " << currentThreadId();Sender sender;connect(&sender, SIGNAL(sig(const QString&, const int&)), this, SLOT(slot_main(const QString&, const int&)));sender.emitsig("thread", 220);exec();
}
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>#include "sender.h"
#include "recver.h"
#include "mythread.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "main thead id is : " << QThread::currentThreadId();//std::cout << std::this_thread::get_id() << std::endl;Mythread mythread;mythread.start();return a.exec();
}
运行效果如下:
如上显示在子线程发送信号,槽函数却在主线程中执行,因为接收者mythread是在主线程中创建。
3.2 槽函数在发送者所在线程执行
mythread.cpp
#include "mythread.h"
#include <QDebug>
#include "sender.h"Mythread::Mythread(QObject* parent) : QThread(parent)
{moveToThread(this);
}void Mythread::slot_main(const QString& str, const int& ci) {qDebug() << "mythread slot_main: " << currentThreadId() << str << ci;
}void Mythread::run() {qDebug() << "mythread thread: " << currentThreadId();Sender sender;connect(&sender, SIGNAL(sig(const QString&, const int&)), this, SLOT(slot_main(const QString&, const int&)));sender.emitsig("thread", 220);exec();
}
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>#include "sender.h"
#include "recver.h"
#include "mythread.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "main thead id is : " << QThread::currentThreadId();//std::cout << std::this_thread::get_id() << std::endl;Mythread mythread;mythread.start();return a.exec();
}
运行效果:
将信号接收者构造函数//moveToThread(this);的注释放开,槽函数在子线程中执行。尽管接收者在主线程中被创建。
如果构造函数注释moveToThread(this);,connect第五个参数修改为Qt::DirectConnection,槽函数也可以在子线程中执行,如下:
connect(&sender, SIGNAL(sig(const QString&, const int&)), this, SLOT(slot_main(const QString&, const int&)), Qt::DirectConnection);
mythread.cpp
#include "mythread.h"
#include <QDebug>
#include "sender.h"Mythread::Mythread(QObject* parent) : QThread(parent)
{//moveToThread(this);
}void Mythread::slot_main(const QString& str, const int& ci) {qDebug() << "mythread slot_main: " << currentThreadId() << str << ci;
}void Mythread::run() {qDebug() << "mythread thread: " << currentThreadId();Sender sender;connect(&sender, SIGNAL(sig(const QString&, const int&)), this, SLOT(slot_main(const QString&, const int&)), Qt::DirectConnection);sender.emitsig("thread", 220);exec();
}
信号发送者在子线程,槽函数也在子线程中执行。
4.发送者所在线程和发送信号线程的区别
有很多人分不清发送者所在线程和发送信号的线程,在此做一下区分说明。发送者所在线程指的是构造发送者对象所在的线程,发送信号线程指的是发送信号所在的线程,即调用emit所在的线程,有些时候这两个线程并不是一个线程。前面说的槽函数在发送者所在线程执行指的是在发送者所在线程,而不是发送信号的线程。如下代码:
mythread.h
#ifndef MYTHRED_H
#define MYTHRED_H#include <QThread>
#include "sender.h"class Mythread : public QThread
{
Q_OBJECTpublic:Mythread(QObject* parent = 0);Mythread(Sender* sender);public slots:void slot_main(const QString& str, const int& ci);protected:void run();private:Sender* m_sender;
};#endif // MYTHRED_H
mythread.cpp
#include "mythread.h"
#include <QDebug>Mythread::Mythread(QObject* parent) : QThread(parent)
{//moveToThread(this);m_sender = nullptr;
}Mythread::Mythread(Sender* sender) {//moveToThread(this);m_sender = sender;
}void Mythread::slot_main(const QString& str, const int& ci) {qDebug() << "mythread slot_main: " << currentThreadId() << str << ci;
}void Mythread::run() {qDebug() << "mythread thread: " << currentThreadId();if (m_sender) {connect(m_sender, SIGNAL(sig(const QString&, const int&)), this, SLOT(slot_main(const QString&, const int&)));m_sender->emitsig("thread", 220);}exec();
}
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include <QThread>
#include <iostream>
#include <thread>
#include <QObject>#include "sender.h"
#include "recver.h"
#include "mythread.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "main thead id is : " << QThread::currentThreadId();//std::cout << std::this_thread::get_id() << std::endl;Sender sender;Mythread mythread(&sender);mythread.start();return a.exec();
}
运行效果如下:
如上,发送者对象在主线程创建,在子线程中发送信号,槽函数是在主线程中执行,而并非在子线程中执行。
相关文章:
Qt中槽函数在那个线程执行的探索和思考
信号和槽是Qt的核心机制之一,通过该机制大大简化了开发者的开发难度。信号和槽属于观察者模式(本质上是回调函数的应用)。是函数就需要考虑其是在那个线程中执行,本文讨论的就是槽函数在那个线程中执行的问题。 目录 1. connect…...
C++ 类模板
目录 前言 类模板语法 类模板和函数模板的区别 类模板没有自动类型推导的使用方式 类模板在模板参数列表中可以有默认参数 类模板中成员函数创建时机 类模板对象做函数参数 指定传入的类型 参数模板化 整个类模板化 类模板与继承 类模板成员函数类外实现 类模板分…...
边缘计算系统设计与实践
随着科技的飞速发展,物联网和人工智能两大领域的不断突破,我们看到了一种新型的计算模型——边缘计算的崛起。这种计算模型在处理大规模数据、实现实时响应和降低延迟需求方面,展现出了巨大的潜力。本文将深入探讨边缘计算系统的设计原理和实…...
【Spark精讲】Spark存储原理
目录 类比HDFS的存储架构 Spark的存储架构 存储级别 RDD的持久化机制 RDD缓存的过程 Block淘汰和落盘 类比HDFS的存储架构 HDFS集群有两类节点以管理节点-工作节点模式运行,即一个NameNode(管理节点)和多个DataNode(工作节点)。 Namenode管理文件系统的命名空…...
贪心算法:买卖股票的最佳时机II 跳跃游戏 跳跃游戏II
122.买卖股票的最佳时机II 思路: 想要获得利润,至少要以两天为一个交易单元,因为两天才会有股价差。因此可以将最终利润进行分解,如prices[3] - prices[0] (prices[3] - prices[2]) (prices[2] - prices[1]) (prices[1] - pr…...
音频DAC,ADC,CODEC的选型分析,高性能立体声
想要让模拟信号和数字信号顺利“交往”,就需要一座像“鹊桥”一样的中介,将两种不同的语言转变成统一的语言,消除无语言障碍。这座鹊桥就是转换器芯片,也就是ADC芯片。ADC芯片的全称是Analog-to-Digital Converter, 即模拟数字转换…...
python 连接SQL server 请用pymssql连接,千万别用pyodbc
pymssql官方介绍文档 python 使用 pymssql连接 SQL server 代码示例: 安装pymssql包: pip install pymssql代码: import pymssqldef conn_sqlserver_demo():# 连接字符串示例(根据您的配置进行修改)conn Nonetry:co…...
IntelliJ IDEA 自带HTTP Client接口插件上传文件示例
如何使用IntelliJ IDEA自带的HTTP Client接口插件进行文件上传的示例。在这个示例中,我们将关注Controller代码、HTTP请求文件(xxx.http),以及文件的上传和处理。 Controller代码 首先,让我们看一下处理文件上传的Co…...
C++中的接口有什么用
2023年12月13日,周三上午 今天上午在适配器模式,我发现如果想真正理解适配器模式,就必须学会使用C中的接口,就必须明白为什么要在C中使用接口,所以重新学习了一下C中的接口 目录 C中的接口有什么用用代码说明“实现多…...
el-table合并相同数据的单元格
相同的数据合并单元格 <el-table :data"userList" :span-method"objectSpanMethod" border><el-table-column type"selection" width"50" align"center" /><el-table-column label"用户名称" a…...
Verilog Systemverilog define宏定义
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 文章前情预告一、define是个啥?二、为什么要使用define三、怎么使用define四、define的横向拓展五、define思想在生活中的体现!六、结论七、参考资料八、…...
51单片机应用从零开始(十一)·数组函数、指针函数
51单片机应用从零开始(九)数组-CSDN博客 51单片机应用从零开始(十)指针-CSDN博客 目录 1. 用数组作函数参数控制流水花样 2. 用指针作函数参数控制 P0 口 8 位 LED 流水点亮 1. 用数组作函数参数控制流水花样 要在51单片机中…...
【PostgreSQL】从零开始:(八)PostgreSQL-数据库PSQL元命令
元命令 postgres# \? General\bind [PARAM]... set query parameters\copyright show PostgreSQL usage and distribution terms\crosstabview [COLUMNS] execute query and display result in crosstab\errverbose show most recent error…...
02 使用Vite创建Vue3项目
概述 A Vue project is structured similarly to a lot of modern node-based apps and contains the following: A package.json fileA node_modules folder in the root of your projectVarious other configuration files are usually contained at the root level, such …...
Shell三剑客:sed(简介)
一、前言 Stream EDitor:流编辑 sed 是一种在线的、非交互式的编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后&…...
tp连接数据库
ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理。采用PDO方式,目前包含了Mysql…...
jmeter,断言:响应断言、Json断言
一、响应断言 接口A请求正常返回值如下: {"status": 10013, "message": "user sign timeout"} 在该接口下创建【响应断言】元件,配置如下: 若断言成功,则查看结果树的接口显示绿色,若…...
dockerfite创建镜像---INMP+wordpress
搭建dockerfile---lnmp 在192.168.10.201 使用 Docker 构建 LNMP 环境并运行 Wordpress 网站平台 [rootdocker1 opt]# mkdir nginx mysql php [rootdocker1 opt]# ls #分别拖入四个包: nginx-1.22.0.tar.gz mysql-boost-5.7.20.tar.gz php-7.1.10.tar.bz2 wor…...
服务器数据恢复—raid5热备盘未激活崩溃导致上层oracle数据丢失的数据恢复案例
服务器数据恢复环境: 某品牌X系列服务器,4块SAS硬盘组建了一组RAID5阵列,还有1块磁盘作为热备盘使用。服务器上层安装的linux操作系统,操作系统上部署了一个基于oracle数据库的OA(oracle已经不再为该OA系统提供后续服务…...
生产派工自动化:MES系统的关键作用
随着制造业的数字化转型和智能化发展,生产派工自动化成为了提高生产效率、降低成本,并实现优质产品生产的关键要素之一。制造执行系统(MES)在派工自动化中发挥着重要作用,通过实时数据采集和智能调度,优化生…...
netty-daxin-2(netty常用事件讲解)
文章目录 netty常用事件讲解ChannelHandler接口ChannelHandler适配器类ChannelInboundHandler 子接口Channel 的状态调用时机ChannelHandler 生命周期示例NettServer&CustomizeInboundHandlerNettyClient测试分析 ChannelInboundHandlerAdapter适配器类SimpleChannelInboun…...
使用playbook部署k8s集群
1.部署ansible集群 使用python脚本一个简单的搭建ansible集群-CSDN博客 2.ansible命令搭建k8s: 1.主机规划: 节点IP地址操作系统配置server192.168.174.150centos7.92G2核client1192.168.174.151centos7.92G2核client2192.168.174.152centos7.92G2 …...
Python基础入门第四节,第五节课笔记
第四节 第一个条件语句 if 条件: 条件成立执行的代码1 条件成立执行的代码2 ...... else: 条件不成立执行的代码1 条件不成立执行的代码2 …… 代码如下: 身高 float(input("请输入您的身高(米):")) if 身高 >1.3:print(f您的身高是{身高},已经超过1.3米,您需…...
基于Java SSM框架实现智能停车场系统项目【项目源码+论文说明】
基于java的SSM框架实现智能停车场系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个智能停车场管理系统,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发。在引言中,作者将论述…...
React系列:useEffect的使用
useEffect的使用 useEffect的第二个参数不同,useEffect的加载不同 当第二个参数为没有的时候 只在组件初始渲染和组件更新之后加载当第二个参数为[] 的时候 只在初始渲染之后加载当第二个参数为[有依赖] 的时候 只在初始渲染之后和依赖修改的时候进行加载 functi…...
Ps:形状工具 - 描边选项
在形状工具的工具选项栏或“属性”面板中,单击“设置形状描边类型” Set shape stroke type菜单图标可打开“描边选项” Stroke Options面板。 描边预设 Stroke Type 默认列出了实线、虚线和点线三种类型的描边,单击可应用。 自己创建并存储的描边类型&a…...
C#基础知识 - 变量、常量与数据类型篇
C#基础知识 - 变量、常量与数据类型篇 第3节 变量、常量与数据类型3.1 C#变量3.1.1 变量使用3.1.2 自定义变量3.1.2 接收用户输入 3.2 C#常量3.2.1 常量的使用 3.3 C#数据类型3.3.1 数据类型之值类型3.3.2 数据类型之引用类型 更多C#基础知识详解请查看:C#基础知识 …...
Java面向对象思想以及原理以及内存图解
文章目录 什么是面向对象面向对象和面向过程区别创建一个对象用什么运算符?面向对象实现伪代码面向对象三大特征类和对象的关系。 基础案例代码实现实例化创建car对象时car引用的内存图对象调用方法过程 成员变量和局部变量作用范围在内存中的位置 关于对象的引用关系简介相关…...
Gitbook----基于 Windows 10 系统本地安装配置 Gitbook 编写属于自己的电子书
查看原文 文章目录 一、安装 Nodejs二、安装 Gitbook三、gitbook 的使用方法四、设计电子书的目录结构五、设置 gitbook 常用配置 一、安装 Nodejs 若要在 Windows 10 系统即本地使用 Gitbook,需要安装 gitlab-cli 工具,而 gitbook-cli 工具是基于 Node…...
springMVC-Restful风格
基本介绍 REST:即Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用. 1.HTTP协议里面,四个表示操…...
视频网站建设价位/企业营销型网站建设
http://zhushou.huihui.cn/ 转载于:https://www.cnblogs.com/webRobot/p/7812916.html...
wordpress wp terms/常州百度seo排名
原文:[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就体现为一个单一的页面。对于这种复杂的页面,我们在设计的…...
wordpress分类目录 菜单 页面/网上营销方法
ssize_t recv(int s, void *buf, size_t len, int flags); --与read相比,只能用于网络套接字文件描述符 --当flags参数的值设置为MSG_PEEK时,recv可以从socket缓存中读取数据,但是不会将缓存中该部分数据清除使用read函数直接读取socket缓存区…...
用cms做网站的缺点/抖音搜索seo软件
.无穷大功率电源供电系统实验目的:1. 理解掌握无穷大功率电源供电系统2. 通过 MATLAB的电力系统工具箱,对无穷大功率电源供电系统进行建模,并观察分析其波形。实验内容:图 2.1 无穷大功率电源供电系统其模型模块名 提取路径无穷大…...
成都市城乡建设局网站/厦门网站推广优化哪家好
开源最前线(ID:OpenSourceTop) 猿妹综合整理项目地址:https://github.com/ouyanghuiyu/chineseocr_lite光学字符识别(OCR)相信大家都不陌生,就是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形…...
企业英文网站建设的重要性/开网店3个月来亏了10万
前文链接:分数的加减法——C语言初学者代码中的常见错误与瑕疵(11) 重构 题目的修正 我抛弃了原题中“其中a, b, c, d是一个0-9的整数”这样的前提条件,因为这种限制毫无必要。只假设a, b, c, d是十进制整数形式的字符序列。 我也不清楚这种题目应该如何…...