线程共享--互斥锁
来源:互联网 发布:青岛齐鲁商品交易软件 编辑:程序博客网 时间:2024/05/22 06:47
在线程应用中,常常会遇到数据的共享问题,利用互斥锁可以有效解决。下面以程序为例:
1.
#include<stdio.h>
#include<osapi/osapi.h>
char g_key[16]; // Generator更新它,Checker获取它
class KeyGenerator : public OS_Thread{
private:virtual int Routine(){
int times=0;
while(1){
for(int i=0;i<16;i++){
g_key[i]=times;
}
times++;
if(times>=128)times=0;
OS_Thread::Msleep(50);
}
return 0;
}
};
class KeyChecker : public OS_Thread{
private:
virtual int Routine(){
while(1){
for(int i=1;i<16;i++){
if(g_key[i]!=g_key[i-1]){
printf("不完整!!\n");
printKey();
return 0;
}
}
OS_Thread::Msleep(50);
}
return 0;//正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main(){//容易出现问题
KeyGenerator a;
a.Run();
KeyChecker b;
b.Run();
getchar();
return 0;
}
2.利用互斥锁
//#define _CRT_SECURE_NO_WARNINGS /* VS2013,2015需要这一行 */
#include <stdio.h>
#include "osapi/osapi.h"
OS_Mutex g_mutex;
char g_key[16]; // Generator更新它,Checker获取它
class KeyGenerator : public OS_Thread
{
private:
virtual int Routine()
{
int times = 0;
while(1)
{
// 更新key
g_mutex.Lock();
for(int i=0; i<16; i++)
{
OS_Thread::Msleep(5);
g_key[i] = times;
}
g_mutex.Unlock();
times ++;
if(times >= 128) times = 0;
//OS_Thread::Msleep(50);
}
return 0;
}
};
class KeyChecker : public OS_Thread
{
private:
// 线程主函数
virtual int Routine()
{
while(1)
{
// 数据处理
// 检查完整性
g_mutex.Lock();
for(int i=1; i<16; i++)
{
if(g_key[i] != g_key[i-1])
{
printf("不完整!!\n");
PrintKey();
//return 0;
}
}
g_mutex.Unlock();
//OS_Thread::Msleep(50);
}
return 0; // 正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main()
{
KeyGenerator a;
a.Run();
KeyChecker b;
b.Run();
getchar();
return 0;
}
3.改进代码
利用拷贝机制,减少了锁机制的应用时间,避免了线程的无限等待。
#include<stdio.h>
#include "osapi/osapi.h"
OS_Mutex g_mutex;//锁机制使用时间不能太长
char g_key[16];
class KeyGenerator :public OS_Thread
{
private:
virtual int Routine(){int times = 0;
while(1)
{
// 生成key: 需要80ms
char key_new[16];
for(int i=0; i<16; i++)
{
OS_Thread::Msleep(5);
key_new[i] = times;
}
// 更新key: 占有锁的时间非常短
g_mutex.Lock();
memcpy(g_key, key_new, 16);
g_mutex.Unlock();
times ++;
if(times >= 128) times = 0;
//OS_Thread::Msleep(50);
printf("写!");
}
return 0;
}
};
class KeyChecker : public OS_Thread
{
private:
// 线程主函数
virtual int Routine()
{
while(1)
{
// 尽量缩短对共享数据的访问时间
char copy[16];
g_mutex.Lock();
memcpy(copy, g_key, 16);
g_mutex.Unlock();
// 数据处理
// 检查完整性
for(int i=1; i<16; i++)
{
if(copy[i] != copy[i-1])
{
printf("不完整!!\n");
PrintKey();
//return 0;
}
} printf("读!\n");
//OS_Thread::Msleep(50);
}
return 0; // 正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main(){
KeyGenerator mytask1;
mytask1.Run();
KeyChecker mytask2;
mytask1.Run();
getchar();
return 0;
}
1.
#include<stdio.h>
#include<osapi/osapi.h>
char g_key[16]; // Generator更新它,Checker获取它
class KeyGenerator : public OS_Thread{
private:virtual int Routine(){
int times=0;
while(1){
for(int i=0;i<16;i++){
g_key[i]=times;
}
times++;
if(times>=128)times=0;
OS_Thread::Msleep(50);
}
return 0;
}
};
class KeyChecker : public OS_Thread{
private:
virtual int Routine(){
while(1){
for(int i=1;i<16;i++){
if(g_key[i]!=g_key[i-1]){
printf("不完整!!\n");
printKey();
return 0;
}
}
OS_Thread::Msleep(50);
}
return 0;//正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main(){//容易出现问题
KeyGenerator a;
a.Run();
KeyChecker b;
b.Run();
getchar();
return 0;
}
2.利用互斥锁
//#define _CRT_SECURE_NO_WARNINGS /* VS2013,2015需要这一行 */
#include <stdio.h>
#include "osapi/osapi.h"
OS_Mutex g_mutex;
char g_key[16]; // Generator更新它,Checker获取它
class KeyGenerator : public OS_Thread
{
private:
virtual int Routine()
{
int times = 0;
while(1)
{
// 更新key
g_mutex.Lock();
for(int i=0; i<16; i++)
{
OS_Thread::Msleep(5);
g_key[i] = times;
}
g_mutex.Unlock();
times ++;
if(times >= 128) times = 0;
//OS_Thread::Msleep(50);
}
return 0;
}
};
class KeyChecker : public OS_Thread
{
private:
// 线程主函数
virtual int Routine()
{
while(1)
{
// 数据处理
// 检查完整性
g_mutex.Lock();
for(int i=1; i<16; i++)
{
if(g_key[i] != g_key[i-1])
{
printf("不完整!!\n");
PrintKey();
//return 0;
}
}
g_mutex.Unlock();
//OS_Thread::Msleep(50);
}
return 0; // 正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main()
{
KeyGenerator a;
a.Run();
KeyChecker b;
b.Run();
getchar();
return 0;
}
3.改进代码
利用拷贝机制,减少了锁机制的应用时间,避免了线程的无限等待。
#include<stdio.h>
#include "osapi/osapi.h"
OS_Mutex g_mutex;//锁机制使用时间不能太长
char g_key[16];
class KeyGenerator :public OS_Thread
{
private:
virtual int Routine(){int times = 0;
while(1)
{
// 生成key: 需要80ms
char key_new[16];
for(int i=0; i<16; i++)
{
OS_Thread::Msleep(5);
key_new[i] = times;
}
// 更新key: 占有锁的时间非常短
g_mutex.Lock();
memcpy(g_key, key_new, 16);
g_mutex.Unlock();
times ++;
if(times >= 128) times = 0;
//OS_Thread::Msleep(50);
printf("写!");
}
return 0;
}
};
class KeyChecker : public OS_Thread
{
private:
// 线程主函数
virtual int Routine()
{
while(1)
{
// 尽量缩短对共享数据的访问时间
char copy[16];
g_mutex.Lock();
memcpy(copy, g_key, 16);
g_mutex.Unlock();
// 数据处理
// 检查完整性
for(int i=1; i<16; i++)
{
if(copy[i] != copy[i-1])
{
printf("不完整!!\n");
PrintKey();
//return 0;
}
} printf("读!\n");
//OS_Thread::Msleep(50);
}
return 0; // 正常退出
}
void PrintKey()
{
printf("Key: ");
for(int i=0; i<16; i++)
printf("%02X ", g_key[i]);
printf("\n");
}
};
int main(){
KeyGenerator mytask1;
mytask1.Run();
KeyChecker mytask2;
mytask1.Run();
getchar();
return 0;
}
0 0
- 线程共享--互斥锁
- 线程共享
- 共享线程
- python基础-Manager进程数据共享、进程互斥锁数据非共享、线程互斥锁数据共享
- 线程共享和非线程共享
- 线程范围内共享数据
- 线程共享2
- 线程范围内数据共享
- QT线程共享数据
- 线程间共享数据
- 线程间数据共享
- 线程间数据共享
- 线程共享的环境
- JVM线程共享问题
- 线程共享方式
- 线程数据共享-ThreadLocal
- 线程范围内共享变量
- 线程共享与私有
- Socket编程------TCP文件传输(文档、声音、图片、视频和压缩包等)
- angularJS培训之$scope和controller
- Date
- 计算几何基础_1
- 201605计划安排
- 线程共享--互斥锁
- 谁在关心toString的性能?
- Elastic Search Search in Deepth
- IOS 将打印字典和数组的内容由字符编码变为中文
- HTTP之Content-Length
- Windows下cucumber的安装
- JAVA POI读写excel
- android studio更改兼容android低版本
- ajax请求绕过同源策略的实现