关于C++内置类型的线程安全

qq1120487384 2014-05-27 01:03:07
今天突然想到一个问题:
在32位CPU上运行的程序,是不是只要C++的内置类型占的字节数小于等于4的都是线程安全的?
在64位CPU上运行的程序,是不是只要C++的内置类型占的字节数小于等于8的都是线程安全的?比如:64位CPU上运行的C++程序,int64是线程安全的,多线程方位这个全局的int64类型的变量不需要加锁?
...全文
257 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-05-27
  • 打赏
  • 举报
回复
都不是线程安全的。 《Windows核心编程》 Synchronization Functions The following functions are used in synchronization. CancelWaitableTimer CreateEvent CreateMutex CreateSemaphore CreateWaitableTimer DeleteCriticalSection EnterCriticalSection GetOverlappedResult InitializeCriticalSection InitializeCriticalSectionAndSpinCount InterlockedCompareExchange InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedIncrement LeaveCriticalSection MsgWaitForMultipleObjects MsgWaitForMultipleObjectsEx OpenEvent OpenMutex OpenSemaphore OpenWaitableTimer PulseEvent QueueUserAPC ReleaseMutex ReleaseSemaphore ResetEvent SetCriticalSectionSpinCount SetEvent SetWaitableTimer SignalObjectAndWait TimerAPCProc TryEnterCriticalSection WaitForMultipleObjects WaitForMultipleObjectsEx WaitForSingleObject WaitForSingleObjectEx
qq1120487384 2014-05-27
  • 打赏
  • 举报
回复
#include "stdafx.h"
#include <Windows.h>
#include <string>
#include <set>
#include <io.h>
#include <fstream>
#include <Windows.h>
#include<time.h>
#include <stdio.h>
#include <process.h>
#include <iostream>

using namespace  std;

__int64 g_int64 = 0;
char log2Write[100];

DWORD __stdcall thread1(LPVOID lpVoid)
{
	while(true)
	{
		g_int64 = 1111111111;
		Sleep(10);
		memset(log2Write, 0x00, 100);
		sprintf_s(log2Write,100,"%lld\r\n", g_int64);
		cout<<log2Write;
		Sleep(250);
	}
	return 1;
}

DWORD __stdcall thread3(LPVOID lpVoid)
{

	while(true)
	{
		g_int64 = 3333333333;
		Sleep(10);
		memset(log2Write, 0x00, 100);
		sprintf_s(log2Write,100,"%lld\r\n", g_int64);
		cout<<log2Write;
		Sleep(250);
	}
	return 1;
}

DWORD __stdcall thread4(LPVOID lpVoid)
{

	while(true)
	{
		g_int64 = 4444444444;
		Sleep(10);
		memset(log2Write, 0x00, 100);
		sprintf_s(log2Write,100,"%lld\r\n", g_int64);
		cout<<log2Write;
		Sleep(250);
	}
	return 1;
}

DWORD __stdcall thread2(LPVOID lpVoid)
{

	while(true)
	{
		g_int64 = 2222222222;
		Sleep(10);
		memset(log2Write, 0x00, 100);
		sprintf_s(log2Write,100,"%lld\r\n", g_int64);
		cout<<log2Write;
		Sleep(250);
	}
	return 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
	DWORD d1,d2,d3;
	CreateThread(NULL, 0, thread1, NULL, 0,&d1);
	CreateThread(NULL, 0, thread2, NULL, 0,&d2);
	CreateThread(NULL, 0, thread3, NULL, 0,&d3);
	Sleep(10000222110);
 return 0;
}
看上面的333333333(只有9个3),实际应该输出10个3,我运行的环境是CPU64位处理器,64位的操作系统。上面4个线程对一个全局的int64 进行无锁的访问,读和写。测试的结果是:程序不会崩溃,但是会出现数据错误。所以我上面提出的设想是不正确的,还是要加锁。
TheNewIpad 2014-05-27
  • 打赏
  • 举报
回复
引用 2 楼 qq1120487384 的回复:
产生这样的想法原因是:64位平台可以运行64位数据指令,处理器一次可提取64位数据(只要两个指令,一次提取8个字节的数据),32位平台可以运行32位数据指令(需要四个指令,一次提取4个字节的数据)。
楼主写个小程序试试吧。 告诉大家,那样是不安全滴。 因为一楼的汇编指令
qq1120487384 2014-05-27
  • 打赏
  • 举报
回复
产生这样的想法原因是:64位平台可以运行64位数据指令,处理器一次可提取64位数据(只要两个指令,一次提取8个字节的数据),32位平台可以运行32位数据指令(需要四个指令,一次提取4个字节的数据)。
TheNewIpad 2014-05-27
  • 打赏
  • 举报
回复
楼主何来如此想法? 然后为何不写个小demo试试呢? a += 10; // mov eax, [a]; // add eax, 10 // mov [a], eax

64,652

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧