线程共享--互斥锁

来源:互联网 发布:青岛齐鲁商品交易软件 编辑:程序博客网 时间: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;
}
0 0
原创粉丝点击