国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

QT初體驗:手把手帶你寫一個自己的串口助手

這篇具有很好參考價值的文章主要介紹了QT初體驗:手把手帶你寫一個自己的串口助手。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

本文記錄一下用QT Creator 寫一個基本功能齊全的串口助手的過程,整個工程只有幾百行代碼,跟著做下來對新手來說可以更快了解整個QT項目的開發(fā)過程和一些常用控件的使用方法。對新手學(xué)習(xí)QT能增強信心,話不多說,正文開始

先看成品:
QT初體驗:手把手帶你寫一個自己的串口助手

制作過程

1. 布局UI界面

(1) 創(chuàng)建QMainWindow工程。這一步就不贅述了,參考:QT C++入門學(xué)習(xí)(1) QT Creator安裝和使用

創(chuàng)建項目時項目名稱可以設(shè)為Serial,基類可以選擇QMainWindow也可以選擇Qwiget。
注意默認(rèn)勾選“Generate form”,生成 ui 窗體文件 mainwindow.ui 后面要用到。

完成后項目文件展示:
QT初體驗:手把手帶你寫一個自己的串口助手

(2)雙擊mainwindow.ui打開UI布局界面,從左側(cè)控件選擇區(qū)找到需要的控件拖動到界面設(shè)計區(qū)的對應(yīng)位置
(請注意:以下提到的擺放位置只放大概位置即可,因為必須借用布局工具才能規(guī)正)

找到Label控件:
QT初體驗:手把手帶你寫一個自己的串口助手
用6個Lable控件分別按下圖所示紅框位置擺放,并且雙擊改顯示的文字,或單擊選擇對應(yīng)Lable后在其右邊屬性設(shè)置界面里的text屬性更改
QT初體驗:手把手帶你寫一個自己的串口助手

QT初體驗:手把手帶你寫一個自己的串口助手

找到Combo Box控件:
QT初體驗:手把手帶你寫一個自己的串口助手
用5個Combo Box控件分別按下圖綠色框所示位置擺放
QT初體驗:手把手帶你寫一個自己的串口助手

找到Push Button控件:
QT初體驗:手把手帶你寫一個自己的串口助手
用5個Push Button控件分別按下圖紫色框所示位置擺放,并且雙擊按鈕改顯示的文字
QT初體驗:手把手帶你寫一個自己的串口助手
找到Check Box控件:
QT初體驗:手把手帶你寫一個自己的串口助手
用6個Check Box控件分別按下圖藍(lán)色框所示位置擺放,并且雙擊更改顯示的文字
QT初體驗:手把手帶你寫一個自己的串口助手
用1個Spin Box控件分別按下圖棕色框所示位置擺放并調(diào)整大小
QT初體驗:手把手帶你寫一個自己的串口助手
最后兩個大的白色區(qū)域就是接收框和發(fā)送輸入框,上面接收框用Plain Text Edit控件,下面輸入框用Text Edit控件
QT初體驗:手把手帶你寫一個自己的串口助手
接收框用的Plain Text Edit控件需要更改屬性為只讀
QT初體驗:手把手帶你寫一個自己的串口助手

2. 添加下拉列表項

5個Combo Box控件分別雙擊添加列表項(端口對應(yīng)的Combo Box不用改)

波特率:
(點擊綠色加號即可添加)
QT初體驗:手把手帶你寫一個自己的串口助手

數(shù)據(jù)位:

QT初體驗:手把手帶你寫一個自己的串口助手

停止位:

QT初體驗:手把手帶你寫一個自己的串口助手

校驗位:

QT初體驗:手把手帶你寫一個自己的串口助手

對于波特率和數(shù)據(jù)位的下拉列表控件還需要通過更改屬性currentIndex屬性,改變默認(rèn)值。波特率默認(rèn)9600,數(shù)據(jù)位默認(rèn)8。

QT初體驗:手把手帶你寫一個自己的串口助手

3. 修改控件名稱

下面對控件進(jìn)行改名,以便對應(yīng)程序中的對象名,用默認(rèn)名不直觀。

如何改名?
點擊控件,找到界面右邊屬性欄的objectName。
QT初體驗:手把手帶你寫一個自己的串口助手

名稱參考下圖:

QT初體驗:手把手帶你寫一個自己的串口助手
注意這一步一定要把對象名設(shè)置對,否則在編譯程序時會有問題。

4. 利用布局工具

第一步放置控件的時候,想必就會發(fā)現(xiàn)根本很難通過鼠標(biāo)拖動的方法完成對齊,這時還得用上方菜單欄的布局工具:
QT初體驗:手把手帶你寫一個自己的串口助手

下圖中的紅框就是布局后才顯示的:
QT初體驗:手把手帶你寫一個自己的串口助手
操作方法是先手動把控件擺放到大概位置,然后鼠標(biāo)左鍵拉一個框選定幾個控件,再點擊上面的布局工具。
接收設(shè)置和發(fā)送設(shè)置就是用了柵格布局,發(fā)送和清空發(fā)送按鈕是垂直布局,串口設(shè)置中是上面部分是柵格布局,然后整體再用垂直布局。布局后的紅框還可以調(diào)整大小

最后這3個框是Group Box控件,雙擊就可以改文字。為啥把這步放最后了是因為發(fā)現(xiàn)Group Box控件放上去后直接選不了里面的控件了,暫時不知道怎么操作。這里跟VS里不一樣,VS就比較方便
QT初體驗:手把手帶你寫一個自己的串口助手

5. 編輯代碼

雙擊打開.pro文件

QT初體驗:手把手帶你寫一個自己的串口助手

core gui后面添加serialport,即 QT += core gui serialport

QT初體驗:手把手帶你寫一個自己的串口助手

mainwindow.h文件源碼:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
#include <QString>
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QTimer>
#include <QPainter>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    QSerialPort *serialPort;//定義串口指針

private slots:

    /*手動連接槽函數(shù)*/
    void manual_serialPortReadyRead();

    /*以下為mainwindow.ui文件中點擊“轉(zhuǎn)到槽”自動生成的函數(shù)*/
    void on_openBt_clicked();

    void on_sendBt_clicked();

    void on_clearBt_clicked();

    void on_btnClearSend_clicked();

    void on_chkTimSend_stateChanged(int arg1);

    void on_btnSerialCheck_clicked();

private:
    Ui::MainWindow *ui;

    // 發(fā)送、接收字節(jié)計數(shù)
    long sendNum, recvNum;
    QLabel *lblSendNum;
    QLabel *lblRecvNum;
    QLabel *lblPortState;
    void setNumOnLabel(QLabel *lbl, QString strS, long num);

    // 定時發(fā)送-定時器
    QTimer *timSend;
    //QTimer *timCheckPort;
};
#endif // MAINWINDOW_H

mainwindow.cpp文件源碼:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QSerialPortInfo"
#include <QSerialPort>
#include <QMessageBox>
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QStringList serialNamePort;

    serialPort = new QSerialPort(this);
    connect(serialPort,SIGNAL(readyRead()),this,SLOT(manual_serialPortReadyRead()));/*手動連接槽函數(shù)*/

    /*找出當(dāng)前連接的串口并顯示到serailCb*/
    //foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
    //{
        //serialNamePort<<info.portName();// 自動掃描當(dāng)前可用串口,返回值追加到字符數(shù)組中
    //}
    //ui->serailCb->addItems(serialNamePort);// 可用串口號,顯示到串口選擇下拉框中
    ui->serailCb->clear();
    //通過QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->serailCb->addItem(info.portName());
    }

    // 發(fā)送、接收計數(shù)清零
    sendNum = 0;
    recvNum = 0;
    // 狀態(tài)欄
    QStatusBar *sBar = statusBar();
    // 狀態(tài)欄的收、發(fā)計數(shù)標(biāo)簽
    lblSendNum = new QLabel(this);
    lblRecvNum = new QLabel(this);
    lblPortState = new QLabel(this);
    lblPortState->setText("Connected");
    //設(shè)置串口狀態(tài)標(biāo)簽為綠色 表示已連接狀態(tài)
    lblPortState->setStyleSheet("color:red");

    // 設(shè)置標(biāo)簽最小大小
    lblSendNum->setMinimumSize(100, 20);
    lblRecvNum->setMinimumSize(100, 20);
    lblPortState->setMinimumSize(550, 20);
    setNumOnLabel(lblSendNum, "S: ", sendNum);
    setNumOnLabel(lblRecvNum, "R: ", recvNum);
    // 從右往左依次添加
    sBar->addPermanentWidget(lblPortState);
    sBar->addPermanentWidget(lblSendNum);
    sBar->addPermanentWidget(lblRecvNum);

    // 定時發(fā)送-定時器
    timSend = new QTimer;
    timSend->setInterval(1000);// 設(shè)置默認(rèn)定時時長1000ms
    connect(timSend, &QTimer::timeout, this, [=](){
        on_sendBt_clicked();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

//檢測通訊端口槽函數(shù)
void MainWindow::on_btnSerialCheck_clicked()
{
    ui->serailCb->clear();
    //通過QSerialPortInfo查找可用串口
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        ui->serailCb->addItem(info.portName());
    }
}

/*手動實現(xiàn)接收數(shù)據(jù)函數(shù)*/
void MainWindow::manual_serialPortReadyRead()
{
    QByteArray recBuf = serialPort->readAll();;
    QString str_rev;

    // 接收字節(jié)計數(shù)
    recvNum += recBuf.size();
    // 狀態(tài)欄顯示計數(shù)值
    setNumOnLabel(lblRecvNum, "R: ", recvNum);

    if(ui->chk_rev_hex->checkState() == false){
        if(ui->chk_rev_time->checkState() == Qt::Checked){
            QDateTime nowtime = QDateTime::currentDateTime();
            str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
            str_rev += QString(recBuf).append("\r\n");
        }
        else{
	        // 在當(dāng)前位置插入文本,不會發(fā)生換行。如果沒有移動光標(biāo)到文件結(jié)尾,會導(dǎo)致文件超出當(dāng)前界面顯示范圍,界面也不會向下滾動。
	        //ui->recvEdit->appendPlainText(buf);
	       
	        if(ui->chk_rev_line->checkState() == Qt::Checked){
	            str_rev = QString(recBuf).append("\r\n");
	        }
	        else
	        {
	            str_rev = QString(recBuf);
	        }
        }
    }else{

        // 16進(jìn)制顯示,并轉(zhuǎn)換為大寫
        QString str1 = recBuf.toHex().toUpper();//.data();
        // 添加空格
        QString str2;
        for(int i = 0; i<str1.length (); i+=2)
        {
            str2 += str1.mid (i,2);
            str2 += " ";
        }
        if(ui->chk_rev_time->checkState() == Qt::Checked)
        {
            QDateTime nowtime = QDateTime::currentDateTime();
            str_rev = "[" + nowtime.toString("yyyy-MM-dd hh:mm:ss") + "] ";
            str_rev += str2.append("\r\n");
        }
        else
        {
            if(ui->chk_rev_line->checkState() == Qt::Checked)
                str_rev += str2.append("\r\n");
            else
                str_rev = str2;

        }
    }
    ui->recvEdit->insertPlainText(str_rev);
    ui->recvEdit->moveCursor(QTextCursor::End);

}

/*打開串口*/
void MainWindow::on_openBt_clicked()
{
    /*串口初始化*/
    QSerialPort::BaudRate baudRate;
    QSerialPort::DataBits dataBits;
    QSerialPort::StopBits stopBits;
    QSerialPort::Parity checkBits;

    // 獲取串口波特率
    // baudRate = ui->baundrateCb->currentText().toInt();直接字符串轉(zhuǎn)換為 int 的方法

    if(ui->baundrateCb->currentText()=="1200")
        baudRate=QSerialPort::Baud1200;
    else if(ui->baundrateCb->currentText()=="2400")
        baudRate=QSerialPort::Baud2400;
    else if(ui->baundrateCb->currentText()=="4800")
        baudRate=QSerialPort::Baud4800;
    else if(ui->baundrateCb->currentText()=="9600")
        baudRate=QSerialPort::Baud9600;
    else if(ui->baundrateCb->currentText()=="19200")
        baudRate=QSerialPort::Baud19200;
    else if(ui->baundrateCb->currentText()=="38400")
        baudRate=QSerialPort::Baud38400;
    else if(ui->baundrateCb->currentText()=="57600")
        baudRate=QSerialPort::Baud57600;
    else if(ui->baundrateCb->currentText()=="115200")
        baudRate=QSerialPort::Baud115200;

    // 獲取串口數(shù)據(jù)位
    if(ui->databitCb->currentText()=="5")
        dataBits=QSerialPort::Data5;
    else if(ui->databitCb->currentText()=="6")
        dataBits=QSerialPort::Data6;
    else if(ui->databitCb->currentText()=="7")
        dataBits=QSerialPort::Data7;
    else if(ui->databitCb->currentText()=="8")
        dataBits=QSerialPort::Data8;

    // 獲取串口停止位
    if(ui->stopbitCb->currentText()=="1")
        stopBits=QSerialPort::OneStop;
    else if(ui->stopbitCb->currentText()=="1.5")
        stopBits=QSerialPort::OneAndHalfStop;
    else if(ui->stopbitCb->currentText()=="2")
        stopBits=QSerialPort::TwoStop;

    // 獲取串口奇偶校驗位
    if(ui->checkbitCb->currentText() == "none"){
        checkBits = QSerialPort::NoParity;
    }else if(ui->checkbitCb->currentText() == "奇校驗"){
        checkBits = QSerialPort::OddParity;
    }else if(ui->checkbitCb->currentText() == "偶校驗"){
        checkBits = QSerialPort::EvenParity;
    }else{

    }

    // 初始化串口屬性,設(shè)置 端口號、波特率、數(shù)據(jù)位、停止位、奇偶校驗位數(shù)
    serialPort->setPortName(ui->serailCb->currentText());
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(dataBits);
    serialPort->setStopBits(stopBits);
    serialPort->setParity(checkBits);

    // 根據(jù)初始化好的串口屬性,打開串口
    // 如果打開成功,反轉(zhuǎn)打開按鈕顯示和功能。打開失敗,無變化,并且彈出錯誤對話框。
    if(ui->openBt->text() == "打開串口"){
        if(serialPort->open(QIODevice::ReadWrite) == true){
            //QMessageBox::
            ui->openBt->setText("關(guān)閉串口");
            // 讓端口號下拉框不可選,避免誤操作(選擇功能不可用,控件背景為灰色)
            ui->serailCb->setEnabled(false);
        }else{
            QMessageBox::critical(this, "錯誤提示", "串口打開失敗?。?!\r\n該串口可能被占用\r\n請選擇正確的串口");
        }
        //statusBar 狀態(tài)欄顯示端口狀態(tài)
        QString sm = "%1 OPENED, %2, 8, NONE, 1";
        QString status = sm.arg(serialPort->portName()).arg(serialPort->baudRate());
        lblPortState->setText(status);
        lblPortState->setStyleSheet("color:green");
    }else{
        serialPort->close();
        ui->openBt->setText("打開串口");
        // 端口號下拉框恢復(fù)可選,避免誤操作
        ui->serailCb->setEnabled(true);
        //statusBar 狀態(tài)欄顯示端口狀態(tài)
        QString sm = "%1 CLOSED";
        QString status = sm.arg(serialPort->portName());
        lblPortState->setText(status);
        lblPortState->setStyleSheet("color:red");
    }

}

/*發(fā)送數(shù)據(jù)*/
void MainWindow::on_sendBt_clicked()
{
    QByteArray array;

    //Hex復(fù)選框
    if(ui->chk_send_hex->checkState() == Qt::Checked){
        //array = QString2Hex(data);  //HEX 16進(jìn)制
        array = QByteArray::fromHex(ui->sendEdit->toPlainText().toUtf8()).data();
    }else{
        //array = data.toLatin1();    //ASCII
        array = ui->sendEdit->toPlainText().toLocal8Bit().data();
    }

    if(ui->chk_send_line->checkState() == Qt::Checked){
        array.append("\r\n");
    }
    // 如發(fā)送成功,會返回發(fā)送的字節(jié)長度。失敗,返回-1。
    int a = serialPort->write(array);
    // 發(fā)送字節(jié)計數(shù)并顯示
    if(a > 0)
    {
        // 發(fā)送字節(jié)計數(shù)
        sendNum += a;
        // 狀態(tài)欄顯示計數(shù)值
        setNumOnLabel(lblSendNum, "S: ", sendNum);
    }
}
// 狀態(tài)欄標(biāo)簽顯示計數(shù)值
void MainWindow::setNumOnLabel(QLabel *lbl, QString strS, long num)
{
    // 標(biāo)簽顯示
    QString strN;
    strN.sprintf("%ld", num);
    QString str = strS + strN;
    lbl->setText(str);
}
/*清空*/
void MainWindow::on_clearBt_clicked()
{
    ui->recvEdit->clear();
    // 清除發(fā)送、接收字節(jié)計數(shù)
    sendNum = 0;
    recvNum = 0;
    // 狀態(tài)欄顯示計數(shù)值
    setNumOnLabel(lblSendNum, "S: ", sendNum);
    setNumOnLabel(lblRecvNum, "R: ", recvNum);
}

void MainWindow::on_btnClearSend_clicked()
{
    ui->sendEdit->clear();
    // 清除發(fā)送字節(jié)計數(shù)
    sendNum = 0;
    // 狀態(tài)欄顯示計數(shù)值
    setNumOnLabel(lblSendNum, "S: ", sendNum);
}
// 定時發(fā)送開關(guān) 選擇復(fù)選框
void MainWindow::on_chkTimSend_stateChanged(int arg1)
{
    // 獲取復(fù)選框狀態(tài),未選為0,選中為2
    if(arg1 == 0){
        timSend->stop();
        // 時間輸入框恢復(fù)可選
        ui->txtSendMs->setEnabled(true);
    }else{
        // 對輸入的值做限幅,小于10ms會彈出對話框提示
        if(ui->txtSendMs->text().toInt() >= 10){
            timSend->start(ui->txtSendMs->text().toInt());// 設(shè)置定時時長,重新計數(shù)
            // 讓時間輸入框不可選,避免誤操作(輸入功能不可用,控件背景為灰色)
            ui->txtSendMs->setEnabled(false);
        }else{
            ui->chkTimSend->setCheckState(Qt::Unchecked);
            QMessageBox::critical(this, "錯誤提示", "定時發(fā)送的最小間隔為 10ms\r\n請確保輸入的值 >=10");
        }
    }
}

如果一切順利的話,點擊左下角的三角符號進(jìn)行編譯運行就可以測試效果了。
QT初體驗:手把手帶你寫一個自己的串口助手

打包可執(zhí)行文件

當(dāng)經(jīng)過上面的步驟,編譯后能成功運行。這時如果希望像我們平時用到的各種免安裝的exe工具一樣可以分享給其他小伙伴使用,就需要再打包一下才行。
傳送門:QT如何打包生成獨立可執(zhí)行.exe文件

遺留問題
本來想定義一個定時器,然后在定時器觸發(fā)的槽函數(shù)中進(jìn)行掃描端口以達(dá)到自動更新端口的效果,就不需要在新插入串口設(shè)備時要點擊一次檢測串口的按鈕。但如果槽函數(shù)中每次都需要先清除之前檢測到的端口,再重新掃描。實際運行時就會出現(xiàn)剛想點開端口下拉列表還沒選就刷新成COM1了,會干擾選擇端口的操作。嘗試了一番不能解決只能作罷。
定時器的槽函數(shù)類似下面這樣(這是一個結(jié)果有問題的示范):

void MainWindow::slot_timCheckPort()
{
    if(ui->openBt->text() == "打開串口"){
        ui->serailCb->clear();
        //通過QSerialPortInfo查找可用串口
        foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
        {
            ui->serailCb->addItem(info.portName());
        }
    }
}

相關(guān)好文推薦:

https://blog.csdn.net/hanhui22/article/details/111594742

https://blog.csdn.net/weixin_46183891/article/details/124368488

https://blog.csdn.net/qq_30255657/article/details/125247114

https://blog.csdn.net/zzssdd2/category_10730183.html

https://blog.csdn.net/Mark_md/article/details/108928314文章來源地址http://www.zghlxwxcb.cn/news/detail-454643.html

到了這里,關(guān)于QT初體驗:手把手帶你寫一個自己的串口助手的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Golang項目實戰(zhàn)】手把手教你寫一個備忘錄程序|附源碼——建議收藏

    【Golang項目實戰(zhàn)】手把手教你寫一個備忘錄程序|附源碼——建議收藏

    博主簡介: 努力學(xué)習(xí)的大一在校計算機(jī)專業(yè)學(xué)生,熱愛學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:數(shù)據(jù)結(jié)構(gòu)、Go,Java等相關(guān)知識。 博主主頁: @是瑤瑤子啦 所屬專欄: Go語言核心編程 近期目標(biāo): 寫好專欄的每一篇文章 前幾天瑤瑤子學(xué)習(xí)了Go語言的基礎(chǔ)語法知識,那么今天我們就寫個

    2024年02月06日
    瀏覽(28)
  • 真手把手帶你跑r3live by 自己設(shè)備 (二)

    真手把手帶你跑r3live by 自己設(shè)備 (二)

    前面詳細(xì)講了如何給電腦連接avia 和 ??倒I(yè)相機(jī),連接后想跑r3live呢,則需要標(biāo)定好相機(jī)內(nèi)參和avia 和相機(jī)之間的外參。 首先標(biāo)定??倒I(yè)相機(jī)的內(nèi)參,則可以用到livox_camera_lidar_calibration幫助我們得到相機(jī)內(nèi)參 by cameraCalib.launch。官方寫的很詳細(xì),直接跑就可以得到參數(shù)了。

    2024年02月17日
    瀏覽(83)
  • 手把手帶你配置一個DHCP服務(wù)器

    最近部門內(nèi)部成立一個網(wǎng)絡(luò)興趣小組,初衷是通過網(wǎng)絡(luò)知識學(xué)習(xí),在遇到網(wǎng)絡(luò)問題時能夠承擔(dān)起一個與網(wǎng)絡(luò)側(cè)同學(xué)有效溝通的“連接人”的角色,求學(xué)這么多年其實也陸續(xù)學(xué)了不少的網(wǎng)絡(luò)相關(guān)課程,本科的計算機(jī)網(wǎng)絡(luò)、碩士的高等計網(wǎng)等,不過當(dāng)時大多都停留在理論層面,趁

    2024年02月05日
    瀏覽(232)
  • 實戰(zhàn)項目:手把手帶你實現(xiàn)一個高并發(fā)內(nèi)存池

    實戰(zhàn)項目:手把手帶你實現(xiàn)一個高并發(fā)內(nèi)存池

    1.這個項目做的是什么? 當(dāng)前項目是實現(xiàn)一個高并發(fā)的內(nèi)存池,他的原型是google的一個開源項目tcmalloc,tcmalloc全稱Thread-Caching Malloc,即線程緩存的malloc,實現(xiàn)了高效的多線程內(nèi)存管理,用于替代系統(tǒng)的內(nèi)存分配相關(guān)的函數(shù)(malloc、free)。 2.項目目標(biāo) 模擬實現(xiàn)出一個自己的高

    2023年04月26日
    瀏覽(58)
  • 手把手自己制作一個飛書機(jī)器人

    手把手自己制作一個飛書機(jī)器人

    飛書機(jī)器人 如果你想添加新的對話邏輯,你只需要在 ChatApi.py 中添加新的if條件判斷語句即可。如果你能開發(fā)出新功能,請在倉庫中提出Pull requests合并請求,我將感激不盡! 2023年9月1日更新 更新了對話機(jī)器人返回幫助界面功能,用戶發(fā)送“幫助”,返回機(jī)器人使用說明 20

    2024年02月03日
    瀏覽(26)
  • 云原生應(yīng)用開發(fā),通過一個案例手把手帶你入門

    針對云勢所趨的市場發(fā)展。云計算和云原生應(yīng)用已經(jīng)成為主流技術(shù)趨勢,學(xué)習(xí)這類技能有遠(yuǎn)見??梢蚤_發(fā)出符合云原生運營模式的應(yīng)用,滿足企業(yè)業(yè)務(wù)發(fā)展需要。 實現(xiàn)資源的高效利用和彈性擴(kuò)展。通過微服務(wù)架構(gòu)、容器技術(shù)、彈性計算等手段,構(gòu)建出計算資源利用高、擴(kuò)展靈活的

    2024年02月06日
    瀏覽(243)
  • 手把手教你寫go單元測試

    ? 在 Go 語言中,單元測試是一種測試方法,用于驗證代碼的某個獨立單元是否按預(yù)期功能,它的目的是確保代碼的每個組成部分都在獨立測試的情況下運行正常。 ? 在我們對項目新增一個新功能時,最好就要養(yǎng)成寫單元測試的好習(xí)慣,這樣可以有助于提高我們代碼的質(zhì)量、

    2024年04月14日
    瀏覽(23)
  • 零基礎(chǔ)手把手教你寫NFT搶購軟

    零基礎(chǔ)手把手教你寫NFT搶購軟

    由于之前寫過幾篇文章,但是個人不是很滿意,所以這次我打算把所有的知識匯總成一篇文章??赡軙泻芏嗟胤綄懙牟皇呛芎?,歡迎大家評論指出,我后續(xù)修正。 個人vx:http://wc.ljlju.cn/4ZGETK 我們在點擊搶購按鈕的時候,會向平臺的服務(wù)器發(fā)送HTTP請求,這條HTTP請求會攜帶你

    2024年02月06日
    瀏覽(44)
  • 手把手教你實現(xiàn)一個JavaWeb項目:創(chuàng)建一個自己的網(wǎng)頁博客系統(tǒng)(前端+后端)(一)

    手把手教你實現(xiàn)一個JavaWeb項目:創(chuàng)建一個自己的網(wǎng)頁博客系統(tǒng)(前端+后端)(一)

    一篇博客帶你實現(xiàn)一個真正的項目! ?先來看看它是什么樣式的: 目錄: 1、大體步驟??: ????????1、創(chuàng)建Maven項目?? ????????2、引入依賴?? ????????3、創(chuàng)建必要的目錄?? ????????4、編寫代碼?? ????????5、打包部署(基于SmartTomcat)?? ????????

    2024年02月06日
    瀏覽(22)
  • 手把手教你寫stm32f103智能風(fēng)扇

    手把手教你寫stm32f103智能風(fēng)扇

    本系統(tǒng)可以分為兩個模式來進(jìn)行運行,分別為手動模式和自動模式,同時,在上電進(jìn)入系統(tǒng)后,還會有一個模式選擇的界面產(chǎn)生。 模式選擇:在此界面中,可以通過按鍵K1來控制模式選擇,兩個模式分別為手動模式和自動模式;通過按鍵K2可以進(jìn)入模式。 手動模式:在手動模

    2023年04月17日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包