多线程如何同步

嗯……线程同步……2 02 2 年,我在做一个使用VC++的项目,多线程很头疼。

第一个临界区,CCriticalSection。
是的,就是这样。
多个线程竞争全局变量等资源,导致它们的值随机变化。
创建 g_CriticalSection 对象。
定义。

然后,如果您想使用该共享资源,请添加 g_CriticalSection.Lock();在前。
这行代码运行线程 A,锁定它,然后允许它访问和修改该变量。
更改完成后,您必须运行 Unlock()。
迅速地。
一旦锁被释放,另一个线程 B 就可以进入该锁并访问它。

感觉就像一扇小门,一次只允许一个人进入。
到2 02 2 年,Windows API中就会出现这样的机制。
如果使用过多,线程可能会挂起而无法输入,导致CPU使用率很高。

二、事件,CEvent。
这太有趣了!线程A专用于一件事,例如监听网络端口。
另一个线程B执行其他处理,例如更新数据库。
线程A已经完成了工作,需要通知线程B,“现在,轮到你了”。
只需使用事件即可。

创建一个CEvent对象,例如notifyEvent。
创建事件时选择自动或手动事件。

自动事件,线程A SetEvent();唤醒线程B。
线程B WaitForSingleObject();等待。
线程 B 被通知其工作已完成并自动执行 Reset()。
然后又回到无信号状态。
这很简单。
不用担心线程B。
线程B会自动重置。

人工事件,线程A SetEvent();启动线程B。
线程B等待...等待。
当时间到时,线程 B 必须调用 ResetEvent()。
手动重置。
否则,线程A下次执行setEvent()时;线程B仍然会在这里等待。

我们将在 2 02 2 年在网络应用程序中使用它。
线程 A 监听端口并接收数据。
SetEvent();通知线程B处理数据。
线程B处理完后,手动Reset();这样,我们下次收集您的数据时就会再次通知您。

只有两种类型:临界区和事件。
用得越多,你就越知道在哪个场景该用哪个。
关键部分确保数据一致性,例如设置共享变量。
事件是线程之间的通知。

python多线程的几种方法

说白了,Python中的多线程同步主要依赖于锁机制,比如Lock和Semaphore。
其实很简单。
锁定用于确保同一时刻只有一个线程可以访问关键资源,而信号量则允许一定数量的线程同时访问资源。

我们先来说说最重要的事情。
使用Lock非常简单。
例如,在这个例子中我们创建了一个 Num 类,它有一个数字计数器和一个锁。
每当调用add方法时,我们首先调用lock.acquire()来锁定,然后触发计数器,最后调用lock.release()来解锁。
我们去年做的项目就采用了这种方法来保证线程安全。

还有一点是Semaphore允许一定数量的线程同时访问资源。
在Num类的构造函数中我们将Semaphore的值设置为3 ,这意味着最多三个线程可以同时执行add方法。
这个细节很重要,因为它决定了同时访问资源的数量。

一开始我以为Semaphore和Lock没有区别,后来发现错了。
信号量更像是一个计数器,可以控制同时访问资源的线程数量。
等等,还有一件事,Semaphore 特别适合控制多线程环境中的并发数,例如数据库连接池。

最后,我认为在实际应用中根据具体场景选择合适的同步机制是值得尝试的。
例如,如果您的应用程序需要严格控制竞争对手的数量,Semaphore 可能是一个不错的选择;而如果你的应用程序只需要保证关键资源的线程安全,Lock就足够了。
很多人没有注意到这一点,但这一点确实很重要。

多线程同步有几种实现方法

我需要和你谈谈这件事。

前年,我在上海,带领一个小团队做一个项目。
系统突然崩溃,数据不匹配。
经过检查,发现是多线程对共享资源的操作控制不当,导致数据乱七八糟。
你知道那种急得满头大汗的感觉吗?所以说,多线程控制确实不是一件小事。

想一想,如果几个线程同时改变变量,就会出现问题。
例如,一个线程加1 ,另一个线程加1 ,最终结果可能不是预期的值。
所以需要锁起来。

同步的方法是使用关键字synchronized。
我告诉你,这些东西非常有用。
例如,如果我有一个 save() 方法,并且我希望它同步,我会添加synchronized:
java 公共同步无效保存(){ //这里写操作
添加此关键字后,该方法一次只能由一个线程执行。
想一想,就像一台服务器一次只能服务一个顾客,不能同时为两边工作一样。
Java 中的每个对象都有一个内置锁,同步方法会获取该锁。
如果一个线程想要执行这个方法,它必须首先获得锁。
如果得不到,它就会等待。
去年我写了一个电子商务系统。
用户在下单时使用此功能,可以避免同时下单时多付款。

同步代码块也使用synchronized,但它应用于一段代码,而不是整个方法。
例如:
java 公共无效更新(){ synchronized (this) { // 使用当前对象锁 //一段时间内只有一个线程可以进入这里执行代码 }
这类似于sync方法,它也采用对象的内置锁。
我在处理用户权限的方法中使用了它,锁定一小部分代码并只允许一个线程更改权限值。

我很少使用 volatile。
我一年前尝试过一次,但我觉得它并不是为了完全取代锁而设计的。
它主要保证变量的可见性,即保证如果一个线程修改了变量的值,另一个线程可以立即看到它。
但它不保证操作的原子性。
例如,i++ 不应该被不精确地使用。
我正在尝试的场景是状态标记。
如果一个线程改变状态,其他线程可以立即知道,这是非常有用的。

ReentrantLock,我用的比较多。
它从Java 5 开始就可用,并且比synchronized更灵活。
您可以手动控制按键获取和释放并设置超时。
比如去年的项目中,我使用ReentrantLock创建了一个复杂的资源调度集,比使用synchronized更容易控制。
您还可以使用它来执行同步功能。

局部变量,这个与线程同步无关。
如果使用ThreadLocal,每个线程都有自己的变量副本,并且不会互相干扰。
我在线程池场景中使用它来处理大数据。
每个线程处理自己的数据块并使用 ThreadLocal 来组装它。
最后,还是非常有效率的。
但这与同步共享资源不同。
它避免了线程之间的共享。

总之,多线程同步要根据情况来选择。
如果很简单,请使用同步。
如果如果比较复杂或者需要很好的控制,可以使用ReentrantLock。
不要盲目使用,使用不当可能会出现问题。
我通过漏洞总结了一下,希望对你有帮助。