参考教材:
Operating Systems: Three Easy Pieces
Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
在线阅读:
http://pages.cs.wisc.edu/~remzi/OSTEP/
University of Wisconsin Madison 教授 Remzi Arpaci-Dusseau 认为课本应该是免费的。
————————————————————————————————————————
这是专业必修课《操作系统原理》的复习指引。
在本文的最后附有复习指导的高清截图。需要掌握的概念在文档截图中以蓝色标识,并用可读性更好的字体显示 Linux 命令和代码。代码部分语法高亮。
操作系统原理不是语言课,本复习指导对用到的编程语言的语法的讲解也不会很细致。如果不知道代码中的一些关键字或函数的具体用法,你应该自行查找相关资料。

七 线程和锁

1、第一章我们介绍过进程。现在我们介绍一种新的抽象:线程(thread)。一个多线程的程序有多个程序计数器(PC),每个PC指向一个线程的下一条准备执行的指令。线程很像进程,不过线程与进程的区别是:一个进程的全部线程共用一个进程的地址空间,而且都可以访问该进程的全部数据。可以把线程看作轻量级的进程。虽然用多线程可以做到的事,用多个进程来做也可以,但是线程之间共用地址空间,因此更容易分享需要共用的数据。进程之间的数据一般是很少共享的。

2、每个进程都要有自己的寄存器,因此在单个CPU核心上通过上下文切换选择不同的线程来执行时,也要将当前线程的寄存器数据保存在线程控制块(thread control block,TCB)中。同样,TCB还要保存线程的其它状态信息,以确保在切换回原线程时能够顺利恢复进度并继续执行。但是切换线程时,地址空间不变。

3、每个线程都要有自己的栈,因此一个多线程的进程含有多个栈,用于保存各个线程自己的局部变量、函数参数和返回值等。但是一个多线程的进程一般只有一个堆。

4、引入线程的原因至少有两个:一是对并行(parallel)执行的要求。二是为了防止进程请求IO时打断本可以继续执行的任务:如果一个进程有多个线程,可以用其中一个线程发起IO请求,剩下的线程继续进行计算,也可以准备请求或同时请求新的IO。于是当一个线程被阻塞时,CPU就可以调度该进程的其它线程继续在当前核心上执行。Web服务器、DBMS(数据库管理系统)等服务器级大型应用几乎无一例外地充分进行了多线程优化。

5、运行下面的代码若干次:
#include
#include
#pragma warning(disable:4996)
using std::thread;
inline void f(const char* _Str) { puts(_Str); }
int main() {
thread t1(f, “A”), t2(f, “B”);
t1.join(); t2.join();
return 0;
}
虽然输出"A"的线程t1的创建总是先于输出"B"的线程t2,但是输出结果并不总是保持相同:

(注:在Linux下,运行g++ demo.cpp -o demo -O2 -m64 -std=c++1y -pthread进行编译)
线程开始执行或执行完毕的次序与其创建顺序无关。
运行下面的代码若干次:
#include
#include
#pragma warning(disable:4996)
using std::thread;
volatile unsigned c = 0;
inline void f(const char* _Str) {
printf("%s: Begin.\n", _Str);
for (unsigned i = 0; i < 1e8; ++i)++c;
printf("%s: End.\n", _Str);
}
int main() {
puts(“Main: Begin.”);
thread t1(f, “A”), t2(f, “B”);
t1.join(); t2.join();
printf(“Main: End. c = %u\n”, c);
return 0;
}
(volatile关键字修饰的变量在被访问时必须老老实实从内存中访问,不能对需要访问该变量的代码进行优化(例如:将上一次读取的该变量的值保存到寄存器,下次读取时直接使用寄存器中的保存结果而不管其在内存中的值是否已改变))
你应该会认为c的值在最终输出时一定是200 000 000。但是:

连最终输出的值也无法确定!这中间发生了什么呢?
过程f的循环部分的汇编代码大概是这样的:
mov 0x8049a1c, %eax
add $0x1, %eax
mov %eax, 0x8049a1c
变量c位于0x8049a1c中,它在循环中会先被放到eax里,然后增加1,再把寄存器eax的值放回内存中去。
假设线程1开始执行时,c = 50。它将c移到eax中,然后递增1。但是这时定时器中断引发了上下文切换,于是eax的值被保存到线程1的TCB中,线程1暂停。而后,线程2开始运行。它先将c移到eax中,但此时线程2获得的c的值是50而不是51。这次线程2能够在定时器中断到来前执行完一次循环,将eax中的值写回到内存,此时c = 51。下一次又轮到线程1运行了,它从上次中断的位置开始继续执行,将线程1暂停执行时eax的值写回内存,此时c = 51。可以看出,其实c应该被增加2次,值为52;但实际上只增加了1次,值为51。
多线程的情况下,对共享资源进行混乱操作,导致整个处理过程变得混乱。这种情况称为竞争条件(race condition)。这导致了计算机的计算结果不再是可确定的。如果用多个线程执行同一段代码会导致竞争条件,就称这段代码所在的位置为临界区(critical section)。也就是说,临界区中的代码是一段访问共享资源的代码。为了避免这种情况,不允许多个线程同时执行临界区的代码。换个说法就是互斥(mutual exclusion,mutex):临界区的代码被一个线程执行时,它不允许被其它线程执行。

6、原子操作(atomic operations)是建设强大而可靠的计算机系统必不可少的一种思想。无论是我们刚才讨论和后续将讨论的简单代码中,还是在文件系统(将在后续章节学习)、DBMS(数据库管理系统)乃至分布式系统(distributed system)里,都充分体现了这种思想。“原子的”(atomic)一词简单解释为“All or nothing”,也就是说一个原子动作要么将其执行完毕,要么不要执行。将一系列指令组合为原子操作后,就称为事务(transaction)。这是数据库并发中的最基本的概念之一。一个事务中的一系列指令,要么全部执行完毕,要么不能开始执行;如果尚未执行完毕而发生故障,则需要撤销(undo)已经进行的操作。
第6点中的代码如果要正确执行,那么就要将一次循环包含的3条汇编指令视为一个原子操作。当中断发生时,不能暂停执行该操作,而是待其执行完毕后再处理中断(切换到其它线程)。硬件提供了同步原语(synchronization primitives)的支持。在硬件与操作系统的支持下,可以将一系列操作合并为原子操作。

7、为了整体执行临界区的操作,需要用到锁(lock)。锁是一种变量,用于刻画锁的状态。一个锁要么不被进程使用(称为可用(available)、解锁(unlocked)或空闲(free)),要么在一个线程执行临界区的代码时被该线程独占(称为acquired,locked或者held)。锁变量还可以保存其它的信息,例如占用该锁的线程,或者等待获得该锁的线程队列。当然这些在锁这个类中不是公有成员,对用户不可见。

8、为了考察一个锁是否能正确、高效地发挥作用,有必要建立相应的评估准则。
第一个评价标准是互斥。换句话说,就是要考察一个锁是否确实能阻止其它进程访问正在被执行的临界区。
第二个评价标准是公平。意即每一个请求获得锁的进程是否总能获得这个锁(即不会饥饿)。
第三个评价标准是性能。考察标准分成单线程、单核心多线程和多核心多线程三种情况。

9、早期的单核计算机中,进程获得锁和释放锁时,分别通过调用硬件指令禁用中断和启用中断来实现。这个方法非常简单,但有许多缺点。首先,禁用和启用中断显然是特权级指令。如果我们要让程序可以实现锁的功能,那么就要允许它们调用特权指令。这自然是很危险的:一个恶意程序可以在获得锁后开始跑一个死循环,于是它就成功霸占了全部CPU时间。其次,禁用和启用中断是对单个CPU核心控制的。如果CPU有多个核心,仍然可以通过其它核心来访问该临界区。此外,禁用中断期间如果其它硬件请求了中断,这些中断就会丢失,这将会导致非常严重的问题:例如在禁用中断期间,硬盘完成了一个读取操作,向CPU发出相应中断。如果这个中断丢失了,那么OS怎样得知何时应该让因为请求读磁盘而被阻塞的进程继续执行呢?并且,中断的开启关闭(屏蔽或解除屏蔽)操作在CPU上执行起来比一般的指令要慢。
所以,禁用中断只在非常少的情况下使用。例如OS在维护自己的数据结构期间会屏蔽中断。这也在一定程度上阻止了处理中断带来的一些问题。

10、有没有其它的方法实现锁?也许可以尝试用专门的标记位来标记锁。当一个线程准备进入临界区时,调用上锁的命令,标记为置位。当从临界区退出后,调用释放的命令,标记位复位。这期间,如果另一个进程准备进入同一个临界区,就要通过忙等待来检测锁的标记为是否为零。只有为零的时候,才可以继续执行。忙等待的代码大致是:
while(flag) {}
这种办法有两个问题:第一个是正确性。设想有一段程序是这样的:
lock();
while (flag) {}
flag = 1;
//Go into the critical section…
首先尝试获得锁。如果这个锁目前空闲(标记位为0),那么该线程成功获得该锁,忙等待的while循环跳过,直接设置标记位为1,此时开始其它线程将不能进入该临界区,临界区只能由获得相应的锁的线程执行。
但是,如果在线程1把标记为设为1之前,调度器就将其暂停并切换了另一个线程,而另一个线程又能在不被打断的情况下成功设置标记位为1并开始执行,那么当再次切换到线程1的时候,由于忙等待已经跳过,线程1实际上也可以进入同一个临界区执行。因此,这样实现的锁实际上连互斥都不能满足。
而且,忙等待会重复检测标记位,其对处理器的性能影响较大。并且,如果两个线程在同一个核心上轮流跑,而其中一个线程在忙等待另一个线程,那么被等待的这个进程反而还无法运行,直到下一次上下文切换。
这个实现方法是行不通的,必须换用其它方法。

11、1960年代的多处理器系统就具有了对锁的硬件支持。现在所有计算机都具备这种支持。只有软硬结合才能解决第10 点提到的软件实现的锁的正确性问题。
Test-and-set是硬件支持的锁机制,也称旋转锁(spin lock)。当一个线程尝试获得一个锁时,检测该锁是否空闲(返回检测结果)。如果空闲,则这个锁会同时被占用。也就是说,在硬件的支持下,检测一个锁是否为空闲和将空闲的锁占用这两个动作可以看成是同时进行的,是原子操作,不能被调度器中止。
我们用第8点给出的评价锁的三个原则来评估test-and-set机制是否正确且高效:
(1)正确性。Test-and-set只允许单个线程访问临界区,而且上锁过程不会像第10点中说的那样被调度器打断。
(2)公平性。如果只是简单实现旋转锁,其实不能保证公平:一个线程获得锁以后,可能会一直执行,直到执行完毕。
(3)性能。如果计算机是单核的,CPU时间会被严重浪费:因为当一个线程在占用临界区时,如果调度器切换了另一个尝试访问临界区的线程,那么这个线程在该时间片内只能进行忙等待,这个时间片就被浪费了。当然,如果计算机是多核的,且请求获得锁的线程数小于等于CPU的核心数,那么正在一个核心上访问临界区的线程与其它尝试获得锁的线程可以分配到不同的CPU核心上。虽然正在等待的线程依旧会浪费所在核心的CPU时间,但是至少没有拖累正在执行的线程的执行进度。
Test-and-set对应x86汇编中的xchg指令。C++11的头文件的std::atomic_flag中提供了这个机制。

12、另一种硬件支持的机制是compare-and-swap(SPARC平台),在x86平台上称为compare-and-exchange。这个指令也是原子的,并需要三个参数:目标内存地址、期望值、新值。运行这个指令时,检测指定的内存地址的值是否为期望的值。若是,则将其修改为指定的新值。若不是,不进行任何操作。
如果进程通过CAS指令尝试获得锁,那么可以把地址参数设为锁的地址,并把期望值设为0,新值设为自己的PID。如果指定地址的值不是0,意味着有进程在占用临界区。如果值为零,那么代表没有进程占用临界区,该进程获得锁,并修改锁变量的值为自己的PID。

13、CPU提供一对指令来构建临界区。MIPS架构的CPU的这对指令被称为load-linked和store-conditional。Alpha、PowerPC、ARM等平台也提供相近的指令。
Load-linked的功能很像一般的Load指令,从内存中取得一个值,然后存入寄存器。但是store-conditional指令只有在刚才load-linked指令读取的地址的值未被更新的时候才执行成功(更新该地址的值为指定的值)。

14、Fetch-and-add机制与compare-and-exchange类似,将目标地址的值自增(+1)的同时返回自增之前的值。
Fetch-and-add可以实现一种新的锁——票锁(ticket lock)。当一个线程想要获得一个锁时,就尝试一次fetch-and-add操作,将这个锁的ticket value增加1。每个线程自己有一个票面值。当锁的票面值与线程的票面值相同时,这个线程进入临界区。需要解锁时,线程将锁的票面值再增加1即可。

15、上面介绍的实现锁的方法都需要在尝试获得锁的线程未获得锁的时候进行忙等待,浪费CPU时间。有没有别的方法可以解决这个问题呢?答案是:让权等待。当线程尝试上锁失败后,立刻释放CPU,不要进行忙等待,让调度器调度其它的进程。让权等待是系统调用,调用的进程被从运行态设为就绪态,然后调度器选择另一个进程运行。这个过程叫做去调度(descheduling)。

16、Linux使用futex(fast userspace mutex)来实现锁机制。在一个线程尝试获得锁失败后,会先忙等待一个比较短的时间、若仍然无法获得锁,则进入睡眠(sleeping)状态(睡眠的线程不会被调度器选择运行,不占用CPU),直到该线程尝试获得的锁变为空闲时才唤醒该线程。
这种两段锁(two-phase lock)方案混用了不同的方法。生活中,混用不同的方案往往效果更好,例如混合制经济。
C++11开始,提供了互斥锁的实现,位于头文件中。

17、线程安全(thread safety),意味着当一个线程在修改为多个线程所共享的数据时,不会有其它线程可以修改这些共享的数据。

18、下面我们列举几个将单线程的数据结构并行化的简单例子,来体会利用锁来将代码正确并行化的可行方法和可能遇到的问题。
一个简易计数器的代码如下:
template class counter {
private:
_Ty value;
public:
counter() { value = 0; }
void increment() { ++value; }
void decrement() { --value; }
_Ty get() { return value; }
};
如何将锁应用到这个数据结构,来使其线程安全呢?一个最简单的想法是:当调用一个需要写入该数据结构的成员函数时,对需要修改的成员变量上锁,直到返回后再释放锁。
我们建立若干个线程,每个线程的任务都是一样的:给这个计数器增加同样多的计数。逐渐增加线程数,每个线程为计数器增加的计数不变,统计总的运行时间。
测试环境:Core i5-8400 2.80 GHz,,Windows 10 Pro,Visual Studio 2019,Release x64
测试代码:
#include
#include
#include
#include
using namespace std; using namespace std::chrono;
template class counter {
private:
_Ty value;
public:
counter() { value = 0; }
void increment() { ++value; }
void decrement() { --value; }
_Ty get() const { return value; }
};
const size_t thread_num = 2;
counter<> c; vector t;
inline void inc() {
for (unsigned i = 0; i < 1e8; ++i)c.increment();
}
int main() {
auto t0 = steady_clock::now().time_since_epoch().count();
for (size_t i = 0; i < thread_num; ++i) { t.emplace_back(thread(inc)); }
for (size_t i = 0; i < thread_num; ++i) { t[i].join(); }
auto t1 = steady_clock::now().time_since_epoch().count();
cout << "Duration = " << (t1 - t0) / 1e6 << "ms.\nThe value of the counter is " << c.get() << endl;
return 0;
}
测试结果:
The number of threads Time elapsed (ms) Total increment count
1 60.9282 108
2 71.5298 108
3 65.9102 108
4 103.584 108
5 90.2162 108
6 111.827 108
7 103.828 108
8 118.452 108
如果用多个线程同时增加计数器的值,不但最后总的增加次数还是108而不是随着线程数的增加而线性增加,而且计数器增加同样的值花费的总时间居然还变多了!
如果增加线程数的同时让总的计数器增加次数不变,结果又如何呢?
测试结果:
The number of threads Increment count of each thread Time elapsed (ms) Total increment count
1 108 68.8759 108
2 5×107 38.2004 5×107
4 2.5×107 31.0144 2.5×107
8 1.25×107 29.9844 1.25×107
可以看出线程数与总的执行时间明显不是反比例关系,执行时间的缩短幅度显著低于预期。
我们回忆前面讲过的竞争条件。函数f执行的过程可能会被编译器优化成这样:先从内存中取得计数器类的实例c,然后把它的成员变量value放入寄存器中,对寄存器中的值增加指定的次数,再把增加完毕的value写回内存。但是在一个线程把增加后的值写入内存之前,其它线程也被创建并执行了——无论它们是在不同的核心上执行的,还是在同一个核心上因为上下文切换才开始执行的,它们从内存中读到的value的初值都是0,而不是先前开始的线程已经增加的值。所以,虽然各个线程实行的自增次数一次都没少,但是这之中有很多自增实际上做了无用功。大家可以自己试着做:如果在创建进程后添加适当的延时,那么可以让计数器总的增加次数与线程数成正比例关系。
还有没有别的方法可以实现呢?
一个办法是:单个线程先在自己的局部变量中自增一定数量,自增完毕后把增加的值累加到作为全局变量的计数器中。当然这种方法也对计数器的精度造成了损失(计数器的值的加减不再精确到1)。具体代码这里不给出,留作练习。

19、对于链表,可以给每个节点都放置一个锁。修改第一个节点时把锁锁住;修改完毕时,先把下一个节点的锁锁住,再释放当前节点的锁。不过,由于这种方法频繁对锁操作,开销也是十分大的;也许可以令多个节点共用一个锁。在将代码并行化的时候,如果需要用到锁机制,务必考虑对锁的访问是否过多。特别是对一些非常底层的代码,尤其是数据结构,能够优化一点,对总体性能的提升也许就非常明显,因为这些代码的使用频率非常高。

20、对于队列,处理就稍微简单些。因为队列只在头尾进行操作,所以把头结点和尾结点各设一把锁即可。在初始化队列的时候,放一个空节点,且这个空节点始终在队列里。这样在队列无有效节点或只有一个有效的节点的时候,仍然可以对头尾同时进行修改操作。具体的实现同样留作练习。

21、对于哈希表,并行化就比较容易了,而且性能提升非常明显。哈希值相同的元素会被装在桶中,桶可以用链表或者平衡树实现。计算哈希的过程自然可以并行化。只要是对不同哈希值的元素进行操作(添加、删除),修改哈希表的过程也可以很容易做到独立进行、互不干扰。
在这里插入图片描述在这里插入图片描述

#include<cstdio>
#include<thread>
#pragma warning(disable:4996)
using std::thread;
inline void f(const char* _Str) { puts(_Str); }
int main() {thread t1(f, "A"), t2(f, "B");t1.join(); t2.join();return 0;
}

在这里插入图片描述在这里插入图片描述

#include<cstdio>
#include<thread>
#pragma warning(disable:4996)
using std::thread;
volatile unsigned c = 0;
inline void f(const char* _Str) {printf("%s: Begin.\n", _Str);for (unsigned i = 0; i < 1e8; ++i)++c;printf("%s: End.\n", _Str);
}
int main() {puts("Main: Begin.");thread t1(f, "A"), t2(f, "B");t1.join(); t2.join();printf("Main: End. c = %u\n", c);return 0;
}

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<thread>
#include<vector>
#include<chrono>
using namespace std; using namespace std::chrono;
template<class _Ty = unsigned> class counter {
private:_Ty value;
public:counter() { value = 0; }void increment() { ++value; }void decrement() { --value; }_Ty get() const { return value; }
};
const size_t thread_num = 2;
counter<> c; vector<thread> t;
inline void inc() {for (unsigned i = 0; i < 1e8; ++i)c.increment();
}
int main() {auto t0 = steady_clock::now().time_since_epoch().count();for (size_t i = 0; i < thread_num; ++i) { t.emplace_back(thread(inc)); }for (size_t i = 0; i < thread_num; ++i) { t[i].join(); }auto t1 = steady_clock::now().time_since_epoch().count();cout << "Duration = " << (t1 - t0) / 1e6 << "ms.\nThe value of the counter is " << c.get() << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. Redis应如何使用?

    Redis列表(List)Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。有序,元素可以重复lpush/rpush <key> <…...

    2024/4/24 8:52:10
  2. 初学JS

    5-28:LeetCode与JSLeetCode每日一题:第一题JS:今日所学总结 LeetCode每日一题:第一题 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使…...

    2024/4/24 8:52:06
  3. 深度学习实践(一)

    模模糊糊的选课终于结束了,猛然发现每周多了一天假期哇(不是) 一直在担心的军事理论也应该能重修了,如果疫情一直没有缓解的话,大方向应该是保研没错了(但真心想考一次托福,也想出去看看呢) 眼看快期末了,把上一周的深度学习入门的东西又看了看。第一次写了一个辨别猫脸的…...

    2024/4/24 8:52:13
  4. 流程控制语句

    第一章 流程控制 1.1 概述 在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。也就是说,程序的流程对运行结果 有直接的影响。所以,我们必须清楚每条语句的执行流程。而且,很多时候我们要通过控制语句的执行顺序来实现 我们要完成的功能。 1.2 顺序结…...

    2024/4/24 8:52:04
  5. Linux——网络应用与服务

    网络应用与服务 客户端必须与它们相应的网络服务器连接起来才能正常工作。Unix服务器有很多种形式。服务器程序直接或间接地监听端口。另外,服务器功能各异,但没有通用的配置数据库。大多数服务器通过配置文件(尽管格式不统一)来定义自身的行为,并使用操作系统的syslog服务…...

    2024/4/24 8:52:03
  6. Python中定时任务框架APScheduler入门教程

    前言 更多内容,请访问我的 个人博客。谈到定时任务,大家可能会优先想到 linux 中的 crontab ,或者 windows 中的任务计划。这些工具用起来都很方便,但是说出来你可能不信,最近我在生信流程中使用 crontab 命令完成一些自动化操作时,遇到问题了。 不知是不是 crontab 命令…...

    2024/4/24 8:52:02
  7. Python 100——Day 5

    练习经典的例子寻找水仙花数(3位)正整数的反转百钱百鸡问题CRAPS赌博游戏斐波那契数列(Fibonacci sequence)前20个寻找完美数(10000以内)100内的素数#三位数的水仙花数 #每个位数上的立方加起来等于这个数 for number in range(100,1000):first = number//100sec = numbe…...

    2024/4/26 14:04:36
  8. CSRF和SSRF漏洞

    CSRF漏洞简介 CSRF(Cross-Site Request Forgery,跨站点伪造请求)是一种网络攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在未授权的情况下执行在权限保护之下的操作,具有很大的危害性。具体来讲,可以这样理解CSRF攻击:攻击者…...

    2024/4/16 13:39:38
  9. 提词器App,录制短视频的神器,解决背台词和卡壳的烦恼

    如果录制短时受背台词和卡壳困扰,那么这个App完全可以解救你。 运行时文稿滚动播放,可以设置文字大小适应远或近的应用场景;滚动速度设置中既可以选择固定速度也可以选择固定时长,无论你是多长的文稿,程序会计算字数和速度,帮你在限定时间内完成,尤其适合微信视频号和抖…...

    2024/5/7 2:50:17
  10. java复习第8天---8.4---IO流---缓冲流

    java复习第8天---8.4---IO流---缓冲流目录文章目录1、缓冲流1.1、概述1.2、原理1.3、BufferedInputStream1.4、BufferedOutputStream1.5、BufferedReader1.6、BufferedWriter1.8、新方法1.7、小案例***后记*** :内容1、缓冲流 1.1、概述缓冲流,又名高效流。是对4个基本流的增…...

    2024/4/19 8:27:53
  11. Java发展历史

    James-Golsing(詹姆斯-高斯林)简介 *1955年 James-Golsing 詹姆斯-高斯林,业内人士也常常调侃为高司令,计算机语言的天才出生了。 高司令14岁在大学计算机中心学习编程,15岁为大学天文系编写了一套分析卫星,处理天文数据的系统,被招聘为临时编程员。 80年代初期,高司令获…...

    2024/5/6 21:37:17
  12. hook进阶:linux下捕获进程的退出

    相信看过前面相关文章的朋友,都可以看出,hook系统调用其实还是比较简单(以open为例):1、获取系统调用表首地址,可以看这篇;2、替换系统调用为自定义的函数(my_hook_open)地址:sys_call_table[__NR_open]=my_hook_open;但是,事情往往不是都那么简单,这种只能hook到系统…...

    2024/4/20 7:06:02
  13. java 内存溢出 栈溢出的原因与排查方法

    https://my.oschina.net/u/2401092/blog/1621850...

    2024/4/15 6:32:57
  14. Java中的四种权限修饰符

    public > protected > (default) > private同一个类 y y y y 我自己同一个包 y y y n 我邻居不同包子类 y y …...

    2024/4/16 13:39:23
  15. 10. 比较两个等长的字符串,若相同,则输出Match!,若不同,则输出No Match!。

    10. 比较两个等长的字符串,若相同,则输出Match!,若不同,则输出No Match!。 data segmentstr1 db computerstr2 db computerlen dw $-str2 ;$有指针的意思mesg1 db Match!$mesg2 db No Match!$ ;$字符串的结束符 data ends code segmentassume c…...

    2024/4/16 13:39:43
  16. 利用Python进行电商网站用户行为分析

    电商网站用户行为分析 项目需求 1.用户整体购物情况怎样?统计数据集中总的用户数,商品数,商品类别数,用户行为数。 核心指标如PV,UV,跳出率,复购率,留存率等分别是多少?2.用户的购物行为情况。 3.统计出每天各种行为的访问次数。 4.找出购买率最高的前二十个商品品类。…...

    2024/4/24 8:52:03
  17. #关于C++派生类构造函数的用法

    本人是小白一名,最近在学习c++。在学习的过程中,遇到c++类继承问题,如何继承基类的构造函数下面直接上例子 class A { public: A(int b) { … … … .}; } class B:public A { public: B(int a):A(a) { … … … } }; 这里小白随便说几句一般都要在类里面声明构造函数是publ…...

    2024/5/6 21:31:30
  18. Gerapy安装macOS

    由于所需众多包版本跟环境的包冲突,所需在虚拟环境中安装本次安装版本 gerapy ==0.9.2 scrapy==1.6.0 #安装scrapy版本太高会导致gerapy初始化失败ps:mac中安装gerapy,由于在虚拟环境中安装会报错:mac “command gcc failed with exit status 1”,解决办法: xcode-s…...

    2024/4/24 8:51:59
  19. Thymeleaf:org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expres问题解决

    我在前端使用Thymeleaf以及layui的表格数据的时候,出现了下面这个问题查阅资料以及参考才发现:原因在于这里进行换行操作问题就轻易解决了:...

    2024/4/24 8:51:58
  20. golang异常处理详解

    小熊今天有意外收获,忍不住给大家分享我愉快的心情!昨天中午下楼取外卖的时候被一个同事认出来了,他问我:“是不是【编程三分钟】的作者,文章写的不错”。 你知道吗!我当时就是一愣,然后差点感动到哭出来,虽然小熊的号比不上大牛的号,不能随便发一篇文章都有成千上万的…...

    2024/4/24 8:51:59

最新文章

  1. IAST面面观 | 解析灰盒测试IAST:原理、实施策略与优势

    近年来&#xff0c;多次发生的数据泄露事件都与应用程序的安全漏洞有关。例如&#xff0c;WannaCry勒索软件攻击就利用了Windows操作系统中的一个漏洞&#xff0c;影响了全球超过150个国家的计算机系统&#xff0c;导致大量数据被加密和丢失。应用程序是黑客尝试突破以访问敏感…...

    2024/5/7 3:18:39
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/5/6 9:38:23
  3. Django auth模块

    【一】命令行创建用户 【1】语法 python manage.py createsuper【2】示例 用户名 默认是是电脑名称 邮箱 可以填也可以不填 密码 terminal中&#xff1a;输入密码不显示出来manage.py中&#xff1a;明文输入输入密码太简单会提示 Username (leave blank to use administra…...

    2024/5/6 15:22:55
  4. STM32--RC522学习记录

    一&#xff0c;datasheet阅读记录 1.关于通信格式 2.读寄存器 u8 RC522_ReadReg(u8 address) {u8 addr address;u8 data0x00;addr((addr<<1)&0x7e)|0x80;//将最高位置一表示read&#xff0c;最后一位按照手册建议变为0Spi_Start();//选中从机SPI2_ReadWriteByte(ad…...

    2024/5/3 10:12:21
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/4 23:54:56
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/4 23:54:56
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/5/4 23:54:56
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/6 9:21:00
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/5/4 23:54:56
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/5/4 23:55:05
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/5/4 23:54:56
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/5/4 23:55:16
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/5/4 23:54:56
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/6 1:40:42
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/5/4 23:54:56
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/5/4 23:55:17
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/5/4 23:55:06
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/5/4 23:54:56
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/4 23:55:06
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/5/5 8:13:33
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/5/4 23:55:16
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/5/4 23:54:58
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/6 21:42:42
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/5/4 23:54:56
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57