今天在一个类A中定义了私有变量member,然后定义了read和write方法用于读取该变量和设置该变量。但是在使用时是在类B中定义了一个A的对象a,然后在a中启动了一个线程t1,在t1中调用a.write(),又启动了一个线程t2,在其中调用了a.read();这样算上主线程,总共3个线程,里面对私有变量menber进行了同时读写。在运行过程中,报2个错:
free(): corrupted unsorted chunks
corrupted size vs. prev_size 内存溢出
后面分析是因为read和write方法中都是用了while(1)进行频繁读写,可能造成了对member的读写抢占,造成出错。后面使用了读写锁解决了上述问题。
1. 引入头文件
#include <pthread.h>
2. 在A类的.h中定义读写锁
pthread_rwlock_t rw_lock;
3. 在对读写共用的变量赋值前后加锁、解锁
加写锁:
pthread_rwlock_wrlock(&rw_lock);//加锁
aImageAddParam.time = tv.tv_sec * 1000000 + tv.tv_usec;
if (len > 0)
{
XXXX
//vecImageParameter为共享的变量
vecImageParameter.push_back(aImageAddParam);
// std::cout << "vecImageParameter size is "<<vecImageParameter.size()<<std::endl;
if (vecImageParameter.size() > vecSize)
{
vecImageParameter.erase(vecImageParameter.begin());
}
XXXXX
}
pthread_rwlock_unlock(&rw_lock);//释放锁
加读锁:
void getVecParameters(std::vector<struct ImageAdditionalParameters> ¶m)
{
pthread_rwlock_rdlock(&rw_lock);//读锁
param = vecImageParameter;
pthread_rwlock_unlock(&rw_lock);//释放锁
}
#pragma comment(lib, "pthreadVC2.lib") //必须加上这句
pthread_t t1; //pthread_t变量t1,用于获取线程1的ID
pthread_t t2; //pthread_t变量t2,用于获取线程2的ID
pthread_rwlock_t rwlock; //声明读写锁
int data=1;
//共享资源
void* readerM(void* arg)
{
while(1)
{
pthread_rwlock_rdlock(&rwlock); //读者加读锁
printf("M 读者读出: %d \n",data); //读取共享资源
pthread_rwlock_unlock(&rwlock); //读者释放读锁
Sleep(1200);
}
return NULL;
}
void* readerN(void* arg)
{
while(1)
{
pthread_rwlock_rdlock(&rwlock);
printf(" N读者读出: %d \n",data);
pthread_rwlock_unlock(&rwlock);
Sleep(700);
}
return NULL;
}
void* writerA(void* arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock); //写者加写锁
data++; //对共享资源写数据
printf(" A写者写入: %d\n",data);
pthread_rwlock_unlock(&rwlock); //释放写锁
Sleep(2000);
}
return NULL;
}
void* writerB(void* arg)
{
while(1)
{
pthread_rwlock_wrlock(&rwlock);
data++;
printf(" B写者写入: %d\n",data);
pthread_rwlock_unlock(&rwlock);
Sleep(2000);
}
return NULL;
}
void main(int argc,char** argv)
{
pthread_rwlock_init(&rwlock, NULL); //初始化读写锁
pthread_create(&t1,NULL,readerM,NULL);
pthread_create(&t1,NULL,readerN,NULL);
pthread_create(&t2,NULL,writerA,NULL);
pthread_create(&t2,NULL,writerB,NULL);
pthread_rwlock_destroy(&rwlock); //销毁读写锁
Sleep(10000000);
return;
}
4. 修改cmakelist.txt
增加pthread到target_link_libraries段中
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -pthread -lboost_filesystem)
endif()
##message(MICROS_VERSION: ${MICROS_VERSION})
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
target_link_libraries(micros_scene_3light_ranging optimized
gimbal_ctrl
pthread
)