day_06_多线程、网络编程

十三、QT多线程(QThread)

1、创建线程方法1:moveToThread

class Worker:public QObject
{
    QOBJECT
public slot:
    void doWork(const QString &parameter){
        QString result;
        /* ..耗时或阻塞的操作.. */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &result);
};

class Controller:public QObject
{
    QOBJECT
    // 创建线程对象
    QThread workerThread;
public:
    Controller() {
        Worker *worker = new Worker;
        // Worker对象移动到线程中
        worker->moveToThread(&workerThread);
        // 当发送operate信号,dowork将在一个独立的线程中执行
        connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
        connect(this, &Controller::operate, worker, &Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        // 开启
        workerThread.start();
    }
    ~Controller() {
        workerThread.quit();
        workerThread.wait();
    }
public slots:
    void handleResults(const QString &);
signals:
    void operate(const QString &);
};

2、创建线程方法2:继承QThread,重写run函数(推荐)

class WorkerThread : public QThread
{
    Q_OBJECT
    // 线程的入口函数
    void run() Q_DECL_OVERRIDE {
        QString result;
        /* 耗时或阻塞的操作 */
        emit resultReady(result);
    }
signals:
    void resultReady(const QString &s);
};

void MyObject::startWorkInAThread()
{
    // 创建线程对象
    WorkerThread *workerThread = new WorkerThread(this);
    connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    // 开启线程
    workerThread->start();
}

3、退出线程

void QThread::exit(int returnCode = 0)
void QThread::quit() [slot]

4、等待线程

bool QThread::wait(unsigned long time = ULONG_MAX)

5、开启线程

void QThread::start(Priority priority = InheritPriority)

6、终止线程

void QThread::terminate()
// 设置线程是否允许被终止(默认:true,设置为false后线程不能被terminate()终止)
void QThread::setTerminationEnabled(bool enabled = true)

7、获取当前线程的句柄(ID)

Qt::HANDLE QThread::currentThreadId()

案例:多线程打印消息
工程名:Thread
类名:ThreadDialog

8、线程同步

1)互斥锁 QMutex
QMutex mutex;
mutex.lock();    // 加锁
mutex.unlock();  // 解锁
2)读写锁 QReadWriteLock
void QReadWriteLock::lockForRead();  // 加读锁
void QReadWriteLock::lockForWrite(); // 加写锁
3)信号量 QSemaphore
QSemaphore::QSemaphore(int n = 0);  // 初始化资源个数为n
void QSemaphore::acquire(int n = 1);// 获取一个资源(p:信号量-1)
void QSemaphore::release(int n = 1);// 释放一个资源(v:信号量+1)

案例:生产者和消费者
问题:
  1)生产者向仓库存放数据,但是如果生产的太快,将会把消费者还未读走的数据覆盖;
  2)消费者从仓库中获取数据,但是如果消费者消费的太快,将会越过生产者,读走一些无效数据;
解决方法:
  使用两个信号量,一个信号量(freeSpace)控制生产者,如果仓库满则等待;另一个信号量(usedSpace)控制消费者,如果仓库空则等待;

/* 生产者线程 */
while(1){
    p(freeSpace)
    // 生产一个产品并存放到仓库
    v(usedSpace)
}
/* 消费者线程 */
while(1){
    p(usedSpace)
    // 从仓库中取出一个产品
    v(freeSpace)
}
4)条件变量 QWaitCondition
QWaitCondition w;  // 创建条件变量
w.wait(&mutex);    // 让当前线程进入休眠,同时解锁
w.wakeAll();       // 唤醒所有等待的线程
w.wakeOne();       // 唤醒一个等待的线程

十四、QT网络编程

1、网络的协议层次(OSI七层)

层次协议
应用层HTTP、FTP、SMTP、POP3、DNS..
表示层
会话层
传输层TCP、UDP
网络层IPv4、IPv6
数据链路层以太网
物理层

扩展:

协议全称
HTTP超文本传输协议(Hyper Text Transfer Protocol)
FTP文件传输协议(File Transfer Protocol)
SMTP简单邮件传输协议(Simple Mail Transfer Protocol)
POP3邮局协议版本3(Post Office Protocol - Version 3)
DNS域名系统(Domain Name System)
TCP传输控制协议(Transmission Control Protocol )
UDP用户数据报协议(User Datagram Protocol)

2、回顾linux的socket编程

1)TCP编程

服务器:
  a. 创建socket套接字:socket()
  b. 准备服务器地址:struct sockaddr_in
  c. 绑定bind()
  d. 监听listen(sfd, 100)
  e. 等待客户端的连接accept()(开启子进程或子线程)
  f. 通信:read()/write()recv()/send()
  g. 关闭close()
客户端:
  a. 创建socket套接字:socket()
  b. 准备服务器地址:struct sockaddr_in
  c. 向服务器发送连接请求:connect()
  d. 通信:read()/write()recv()/send()
   f. 关闭close()

2)UDP编程

服务器端:
  a. 创建socket套接字socket()
  b. 准备服务器地址struct sockaddr_in
  c. 绑定bind()
  d. 通信:recvfrom()/sendto()
  e. 关闭

客户端:
  a. 创建socket套接字:socket()
  b. 准备服务器地址:struct sockaddr_in
  c. 通信:read()/recvfrom()/sendto()
  e. 关闭close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值