int m_g_i = 0; // 定义全局变量 供多个线程操作
void Thread_Proc_0(void* arg)
{
m_g_i = m_g_i + 1; // 线程0 对m_g_i进行+1操作
return ;
}
void Thread_Proc_1(void* arg)
{
m_g_i = m_g_i + 1; // 线程1 对m_g_i进行+1操作
return;
}
int main(int argc, char* argv[])
{
thread_t thread_id_0, thread_id_1;
// 创建线程0 执行m_g_i的累加
pthread_create(&thread_id_0, NULL, Thread_Proc_0, NULL);
// 创建线程1 执行m_g_i的累加
pthread_create(&thread_id_1, NULL, Thread_Proc_0, NULL);
printf("m_g_i = %d \r\n", m_g_i);
return 0;
}
/*
期望程序运行 结束以后 m_g_i 的数值为2
但是有可能m_g_i的数值依旧是1
对于单核CPU m_g_i = 2 是没有问题的,但是对于在多线程(多CPU)中运行 就会
有问题, 因为在多核CPU中,每条线程可能运行于不同的CPU中,因此每个CPU在运行
每条线程时,都有自己的高速缓存(Cache),
初始时,两个线程分别读取m_g_i的值到各自的CPU的高速缓存中去(Cache), 然后线程0
执行加1操作,然后将计算的结果写回内存中去,此时线程1的高速缓存中的m_g_i还是0
进行加1操作,m_g_i的数值为1,再将m_g_i的值写入到内存中去,最终的结果变成m_g_i
为1,而不是2,我擦.....
原因:
多核CPU的缓存不一致导致的,如果一个变量在多个CPU中都存在缓存(一般在多线程编
程时才会出现),那么就可能存在缓存不一致的问题。
解决:
1. 通过在总线加LOCK#锁的方式
加锁会导致CPU无法访问内存,导致效率不高;
2. 通过缓存一致性协议
缓存一致性协议 ---> Intel的MESI协议,
MESI协议保证了每个缓存中使用的共享变量的副本是一致的。它核心的思想是:当CPU写数 据时,如果发现操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号 通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现
自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。
*/