- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
您好,我想要一个 int 和 float 示例,它们会导致使用非原子值写入时出现撕裂。我似乎无法重现这一点。这似乎是非常罕见的事情,或者我做错了什么。
这是我从未打印过的测试代码。有什么问题吗?
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#define MAX_THREADS 64
#define BUF_SIZE 255
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
// Sample custom data structure for threads to use.
// This is passed by void pointer so it can be any data type
// that can be passed using a single void pointer (LPVOID).
typedef struct MyData {
int val1;
int val2;
} MYDATA, *PMYDATA;
int _tmain()
{
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
// Create MAX_THREADS worker threads.
for( int i=0; i<MAX_THREADS; i++ )
{
// Allocate memory for thread data.
// Create the thread to begin execution on its own.
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
NULL, // argument to thread function
0, // use default creation flags
&dwThreadIdArray[i]); // returns the thread identifier
// Check the return value for success.
// If CreateThread fails, terminate execution.
// This will automatically clean up threads and memory.
if (hThreadArray[i] == NULL)
{
ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
} // End of main thread creation loop.
// Wait until all threads have terminated.
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
// Close all thread handles and free memory allocations.
for(int i=0; i<MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
}
return 0;
}
#pragma pack(push, 1)
struct Test
{
char x1;
char x1;
char x3;
int test;
char x4;
char x5;
};
Test* t = new Test(); //This is test code don't care about allocation or that it is a global.
#pragma pack(pop)
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
HANDLE hStdout;
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;
// Make sure there is a console to receive output results.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;
static int thread = 0;
StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Starting thread, %d\n"), ++thread);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);
t->test = 1;
for (int i=0; i<1000000000;++i)
{
t->test = 1;
t->test = 10000;
t->test = 10000000;
int result = t->test;
if(result != 1 && result != 10000 && result != 10000000)
{
StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Tearing occured = %d\n"), result);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);
}
}
return 0;
}
void ErrorHandler(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code.
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message.
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);
// Free error-handling buffer allocations.
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
最佳答案
当使用 Visual Studio 2013 编译时,我可以使用此测试代码触发读取/写入中断,这会强制竞争的 uint32_t 跨越缓存行边界(似乎只发生在发布版本中):
#include <algorithm>
#include <atomic>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
using namespace std;
atomic<bool> gDone = false;
vector<uint32_t> vals = {0x11111111, 0x22222222, 0x33333333, 0x44444444, };
mutex ioMutex;
void writeVal(volatile uint32_t* pVal, int tid) {
while (!gDone) {
*pVal = vals[tid];
const auto currentVal = *pVal;
auto findIt = find(begin(vals), end(vals), currentVal);
if (findIt == end(vals)) {
unique_lock<mutex> ul(ioMutex);
cout << "Detected torn read/write! pVal = 0x" << setbase(16) << setw(8) << setfill('0')
<< reinterpret_cast<uintptr_t>(pVal) << " currentVal = 0x" << currentVal << endl;
gDone = true;
}
}
}
int main() {
vector<char> memVec(16 * 1024);
char* first = &memVec[0];
const auto cacheLineSize = 64;
char* crossesCacheLine =
reinterpret_cast<char*>((reinterpret_cast<uintptr_t>(first + cacheLineSize) & ~(cacheLineSize - 1)) - 2);
uint32_t* tearableUint32 = reinterpret_cast<uint32_t*>(crossesCacheLine);
vector<thread> threads(vals.size());
for (int i = 0; i != threads.size(); ++i) {
threads[i] = thread([=] { writeVal(tearableUint32, i); });
}
for (auto& t : threads) {
t.join();
}
}
输出:
Detected torn read/write! pVal = 0x004bc43e currentVal = 0x11112222
关于c++ - 导致非原子撕裂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25794803/
我设置了一个 JTable 并使其包含 18 列。最初,当它有 13 列时,它很适合 JTable 并且没有撕裂。但是,一旦我让它包含 18 个表,并将 autoresize 设置为关闭,当我使用水平
假设最新的应用程序发布版本是版本号 20。到目前为止,到版本号 20 为止已有 10 次核心数据迁移。例如:使用版本3的用户,直接自动更新到版本20。 我想删除 coredata 堆栈并重建它。但它能
当在 QLabel 上显示图像时,有谁知道在 Qt 中执行 vsync 的简单方法?基本上,我从处理过的视频剪辑中渲染图像流(因此不使用 Phonon 多媒体),并且帧率非常高。不幸的是,这造成了很多
我正在尝试弄清楚如何解决我的问题。我读过 http://groups.google.com/group/android-developers/browse_thread/thread/a2aac88a
我有一个带有 win32 api 的 OpenGL 应用程序,没有过剩等......我遇到了全屏屏幕撕裂的问题。基本上,我将 WS_POPUP 设置为窗口样式,并将显示器的分辨率设置为窗口大小。我在
我在 Win10 主机上运行 Ubuntu 虚拟机(通过 vagrant)并且无法获取 tmux运行时行为正常 vim在其中一个 Pane 中。独立,vim显示正常;然而,当在 tmux 中时 Pan
我正在使用 WriteableBitmap以每秒大约 20 帧的速度显示我自己处理的图像。 这个问题(WPF: More efficient way of displaying quickly-cha
更新:这整个问题最终成为系统图形驱动程序的问题,而不是(看似)浏览器/API 问题。撕裂的框架归结为实际的显示更新。再次感谢那些参与讨论并试图提供帮助的人。 我的页面使用 Canvas 和 2d 上下
我一直在玩 pygame(在 Debian/Lenny 上)。 它似乎工作得很好,除了令人讨厌的 blit 撕裂(全屏或窗口模式)。 我正在使用默认的 SDL X11 驱动程序。谷歌搜索表明,SDL
令我失望的是,我发现我正在开发的应用程序之一在某些计算机上呈现效果相当差。 UI静态图形和文本在没有做任何动画的情况下会出现严重的撕裂情况。这使得文本不可读,当然,图形看起来也很差。 我在不同的计算机
我有一张绘制到 Canvas 上的等轴测图。当我尝试四处移动 map 时,这些黑线在一些图 block 之间闪烁,使整个图看起来很粗糙。 这是我更新线程中的相关代码 public void run()
我认为我的 DirectX 11 应用程序在以前的系统上运行良好(我有大约 70% 的把握)。但是现在,在 Windows 10(笔记本电脑)中我只在全屏模式下有撕裂问题(窗口模式下没有任何撕裂)。
我是一名优秀的程序员,十分优秀!