如果只有一个线程使用互斥锁,跨线程的共享内存会损坏吗?
Will shared memory across threads get corrupted if only one thread uses mutex?
我有一种情况需要跨线程访问共享内存中的变量。该变量最初在许多地方的现有代码中定义并不断更新。我添加的代码将允许此现有代码库 运行 作为后台线程,但我需要从该共享变量中读取数据。
我的问题是我是否需要在每次更新现有代码库时都添加一个互斥体?或者我可以在读取数据时向新代码添加互斥锁吗?我在下面创建了以下似乎可以锻炼的小测试用例。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct my_data {
int shared;
}MY_DATA;
MY_DATA data;
pthread_mutex_t lock;
void *background(void *x_void_ptr)
{
int i = 0;
int sleep_time;
while(i < 10)
{
data.shared++;
printf("BACK thread, Data = %d\n", data.shared);
sleep_time = rand()%5;
sleep(sleep_time);
i++;
}
return NULL;
}
int main()
{
int sleep_time;
pthread_t bg_thread;
if(pthread_create(&bg_thread, NULL, background, NULL)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
MY_DATA *p_data = &data;
int i = 0;
while(i < 10)
{
pthread_mutex_lock(&lock);
printf("FOR thread, Data = %d\n", p_data->shared);
pthread_mutex_unlock(&lock);
sleep_time = rand()%5;
sleep(sleep_time);
i++;
}
// Finish up
if(pthread_join(bg_thread, NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
return 0;
}
输出:
FOR thread, Data = 0
BACK thread, Data = 1
BACK thread, Data = 2
FOR thread, Data = 2
FOR thread, Data = 2
BACK thread, Data = 3
BACK thread, Data = 4
BACK thread, Data = 5
FOR thread, Data = 5
BACK thread, Data = 6
BACK thread, Data = 7
BACK thread, Data = 8
FOR thread, Data = 8
FOR thread, Data = 8
BACK thread, Data = 9
FOR thread, Data = 9
BACK thread, Data = 10
FOR thread, Data = 10
FOR thread, Data = 10
FOR thread, Data = 10
在运行多次使用之后,看起来没有数据损坏(即前台正在读取正确的数据),但我的直觉是我需要在两个前后台代码。
不,你的记忆不会被破坏,阅读对此没有任何影响。
但是你会在不一致的状态下阅读,这同样糟糕。
正在将 material 从我的 转移到答案中。
请注意,进程中的所有全局内存(线程本地存储和函数中的局部变量除外)在线程之间共享。共享内存是进程间共享内存的术语。
无论线程或进程正在访问内存,只要有多个执行线程可以同时访问同一内存,您就需要确保正确管理访问(例如使用互斥锁)。如今,假设您在一台机器上有一个核心在工作是很不安全的,因此潜在的并发访问是常态。
我有一种情况需要跨线程访问共享内存中的变量。该变量最初在许多地方的现有代码中定义并不断更新。我添加的代码将允许此现有代码库 运行 作为后台线程,但我需要从该共享变量中读取数据。
我的问题是我是否需要在每次更新现有代码库时都添加一个互斥体?或者我可以在读取数据时向新代码添加互斥锁吗?我在下面创建了以下似乎可以锻炼的小测试用例。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct my_data {
int shared;
}MY_DATA;
MY_DATA data;
pthread_mutex_t lock;
void *background(void *x_void_ptr)
{
int i = 0;
int sleep_time;
while(i < 10)
{
data.shared++;
printf("BACK thread, Data = %d\n", data.shared);
sleep_time = rand()%5;
sleep(sleep_time);
i++;
}
return NULL;
}
int main()
{
int sleep_time;
pthread_t bg_thread;
if(pthread_create(&bg_thread, NULL, background, NULL)) {
fprintf(stderr, "Error creating thread\n");
return 1;
}
MY_DATA *p_data = &data;
int i = 0;
while(i < 10)
{
pthread_mutex_lock(&lock);
printf("FOR thread, Data = %d\n", p_data->shared);
pthread_mutex_unlock(&lock);
sleep_time = rand()%5;
sleep(sleep_time);
i++;
}
// Finish up
if(pthread_join(bg_thread, NULL)) {
fprintf(stderr, "Error joining thread\n");
return 2;
}
return 0;
}
输出:
FOR thread, Data = 0
BACK thread, Data = 1
BACK thread, Data = 2
FOR thread, Data = 2
FOR thread, Data = 2
BACK thread, Data = 3
BACK thread, Data = 4
BACK thread, Data = 5
FOR thread, Data = 5
BACK thread, Data = 6
BACK thread, Data = 7
BACK thread, Data = 8
FOR thread, Data = 8
FOR thread, Data = 8
BACK thread, Data = 9
FOR thread, Data = 9
BACK thread, Data = 10
FOR thread, Data = 10
FOR thread, Data = 10
FOR thread, Data = 10
在运行多次使用之后,看起来没有数据损坏(即前台正在读取正确的数据),但我的直觉是我需要在两个前后台代码。
不,你的记忆不会被破坏,阅读对此没有任何影响。 但是你会在不一致的状态下阅读,这同样糟糕。
正在将 material 从我的
请注意,进程中的所有全局内存(线程本地存储和函数中的局部变量除外)在线程之间共享。共享内存是进程间共享内存的术语。
无论线程或进程正在访问内存,只要有多个执行线程可以同时访问同一内存,您就需要确保正确管理访问(例如使用互斥锁)。如今,假设您在一台机器上有一个核心在工作是很不安全的,因此潜在的并发访问是常态。