qt-thread competition for shared resources and read-write locks--QReadWriteLock


1. The concept of thread competition

2. What is thread competition

Thread competition refers to the problems that may arise when multiple threads access and modify shared resources at the same time in a multi-threaded environment.
When multiple threads compete to read, write or modify the same resource at the same time, unpredictable results may result, including program crashes, data corruption, or logic errors.

Problems that thread contention can cause include:

  • Data competition: Multiple threads read and write shared variables at the same time, 导致数据的值无法预测或出现错误结果.
  • Race condition: The order and timing of execution of multiple threads are uncertain, resulting in inconsistent final results.
  • Deadlock: multiple threads wait for each other to release resources, resulting in the inability of the program to continue executing.
  • Livelock: Multiple threads cannot make progress, each thread is constantly retrying, but unable to complete the task.
  • Hunger: A thread cannot obtain the resources it needs, so it has been unable to execute.

In order to avoid problems caused by thread competition, it is necessary to use appropriate methods 同步机制和技术, such as 互斥锁、条件变量、原子操作etc., to protect the access, modification and use of shared resources. Properly designing and implementing multithreaded programming is an important step in ensuring program security and stability.

2. What is thread competition for shared resources?

  • In threaded concurrent programming, thread contention occurs when multiple threads simultaneously access and modify a shared resource.
  • Shared resources can be data structures, variables, files, or other objects that can be accessed by multiple threads.

Thread competition for shared resources can cause the following problems:

  • Data Inconsistency: When multiple threads read and write to a shared resource concurrently, they may produce inconsistent results.例如,一个线程正在读取数据,而另一个线程正在同时修改该数据,这可能导致读取到的数据是过时或不正确的。
    one for reading and one for writing

  • Data loss: If multiple threads write to a shared resource at the same time, the write result of one thread may be overwritten by the write of other threads, resulting in data loss.
    insert image description here

  • Program crashes: Thread contention can also cause program crashes or deadlocks. When multiple threads are accessing a shared resource, if they do not do so properly synchronized and mutually exclusive, a deadlock situation can result, in which the threads are unable to continue executing while waiting for each other to release the resource.

2. Read-write lock

1. The concept of read-write lock

  • Read-write lock is a thread synchronization mechanism, 用于解决多线程环境下的读写竞争问题.
  • 读写锁允许多个线程同时获取读锁(共享访问)但只允许一个线程获取写锁(独占访问)
  • This mechanism can improve concurrency performance because 多个线程可以同时读取共享资源而不会相互干扰.

2. The working principle of the read-write lock is as follows:

  • When threads wish to read a shared resource, they can acquire a read lock. Multiple threads can 同时持有读锁, so they can read shared resources in parallel.
    insert image description here

  • When a thread wishes to modify (write to) a shared resource, 它必须获取写锁。写锁是独占的,即只允许一个线程持有写锁,其他线程无法获取读锁或写锁。这确保了在写入操作期间的独占访问,防止其他线程同时读取或写入共享资源.

  • When a thread holds a write lock, other threads' read and write lock requests are blocked until the write lock is released.
    insert image description here

  • By using read-write locks, the problem of thread competition for shared resources can be effectively solved, and the concurrent performance and stability of the program can be improved.

3. An example of using a read-write lock (QReadWriteLock)

In multi-threaded programming, the following points need to be paid attention to when using read-write locks:

  1. Determine the granularity of the lock according to the actual situation: the granularity of the lock should be as small as possible to allow more concurrent access. If the lock granularity is too large, it may lead to a decrease in concurrency performance.

  2. Correct order of acquiring and releasing locks: When using multiple locks, you need to ensure that locks are acquired and released in the correct order to avoid deadlock or race condition issues.

The following is a simple example that demonstrates how to use Qt's read-write lock (QReadWriteLock) in C++ to protect secure access to shared resources:

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

#include <QObject>
#include <QThread>
#include <QReadWriteLock>

class Example : public QObject
{
    
    
    Q_OBJECT

public:
    explicit Example(QObject *parent = nullptr);
    ~Example();

    void start();

private:
    QReadWriteLock m_rwLock;    // 读写锁
    int m_sharedData;			// 共享资源

signals:
    void dataRead(int value);		// 读数据
    void dataWritten(int value);	// 写数据

public slots:
    void readData();             
    void writeData();
};

#endif // EXAMPLE_H

example.cpp

#include "example.h"
#include <QDebug>

Example::Example(QObject *parent) : QObject(parent)
{
    
    
    m_sharedData = 0;   // 初始化变量=0
}

Example::~Example()
{
    
    
}

// 开启线程
void Example::start()
{
    
    
    QThread readerThread;
    QThread writerThread;

    connect(&readerThread, &QThread::started, this, &Example::readData);
    connect(&writerThread, &QThread::started, this, &Example::writeData);

    readerThread.start();
    writerThread.start();
}

void Example::readData()
{
    
    
    while (true) {
    
    
        m_rwLock.lockForRead();
        qDebug() << "Read Data:" << m_sharedData;
        m_rwLock.unlock();
        QThread::msleep(500);
    }
}

void Example::writeData()
{
    
    
    while (true) {
    
    
        m_rwLock.lockForWrite();
        m_sharedData++;
        qDebug() << "Write Data:" << m_sharedData;
        m_rwLock.unlock();
        QThread::msleep(1000);
    }
}

In the above example, we created a shared integer variable sharedDataand QReadWriteLockprotected its access with
readDataRead shared data when the function uses a read lock, and writeDataincrease shared data when the function uses a write lock.

By using the read-write lock, we ensure concurrent access when reading shared resources, and only allow one thread exclusive access when writing shared resources, thereby solving the problem of thread competition for shared resources.

3. Summary:

In thread concurrent programming, thread competition for shared resources is a common problem, which may lead to serious consequences such as data inconsistency, data loss, or program crashes.
Using a read-write lock is an effective solution, which allows multiple threads to read the shared resource at the same time, but only allows one thread to write to the shared resource. This can improve the concurrency performance and stability of the program.

Hope this blog is helpful to you!

Guess you like

Origin blog.csdn.net/ljn1046016768/article/details/131429413