【发布时间】:2016-09-27 19:21:03
【问题描述】:
我正在尝试读取 -> 加密/解密 -> 逐个扇区地在卷上写入原始数据。我需要以某种方式优化时间,因为仅 2GB 的卷需要 2 个多小时(我的卷 G:这里)。我尝试使用线程来处理时间问题,但没有显着的效果。该程序需要在日常使用的 PC 上运行。
每个线程在与其他线程不同的扇区块上运行。
我知道的事情:
- 写时不能读(所以我处理了临界区问题)
- 线程中的读/写会因寻道时间等而减少时间。
- 由于延迟(由读/写头来回移动引起。(给出错误 DEVICE_NOT_READY)),太多线程可能无法完成任务
我想问:
- 我能否利用线程同时在两个不同的扇区上进行读写操作(因为我知道磁盘操作是使用已回答 here 的调度算法执行的)?
- 为什么程序在一个线程(在一个扇区上)写入期间,其他线程尝试读取(在另一个扇区上)时会产生错误?
- 您会建议哪些修改来缩短时间?
代码:
DWORD WINAPI EncryptSectorBlock(LPVOID lpParam)
{
PTARGS args = (PTARGS)lpParam;
static unsigned char buffer[SECTOR_SIZE];
printf("Thread No:%i start:%i end:%i\n ", args->thread_id, args->sector_start, args->sector_end);
for (int i = args->sector_start; i <= args->sector_end; i++)
{
//Entering critical section of the code. The Other Threads Would be first spin with 65536 loops and then set to
// sleep until the worker threads releases the lock on critical section
if (ReadSector(args->read, buffer, SECTOR_SIZE, i) != 1)
printf("Thread: %i. Error reading sector %i\n",args->thread_id, i);
else
printf("Thread: %i. Read Sector %i Successfully\n", args->thread_id, i);
xts_encrypt_sector(buffer, i, SECTOR_SIZE, &(args->ctx));
//Critical Section starts
EnterCriticalSection(&CriticalSection);
if (WriteSector(args->write, buffer, SECTOR_SIZE, i) != 1)
printf("Thread: %i. Error writing sector %i\n",args->thread_id ,i);
else
printf("Thread: %i. Wrote Sector %i Successfully\n", args->thread_id, i);
//Critical Section Ends
LeaveCriticalSection(&CriticalSection);
//init to zero every time in case a sector is failed to be read or write, so it can recover from fault
//This may break in future.. Not proper mechanism to recover from fault. just a hack.
memset(buffer, 0, SECTOR_SIZE);
}
return 0;
}
INT_RETURN EncryptFullVolume(wchar_t* volume, unsigned char* key)
{
//init variables here
for (int i = 0; i < MAX_Threads; i++)
{
ArgsDataArray[i] = (PTARGS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TARGS));
if (ArgsDataArray[i] == NULL)
{
// If the array allocation fails, the system is out of memory
// so there is no point in trying to print an error message.
// Just terminate execution.
ret = EXIT_FAILURE;
}
else
{
// Generate unique data for each thread to work with here
// Create the thread to begin execution on its own.
hThreadArray[i] = CreateThread(
NULL, // default security attributes
0, // use default stack size
EncryptSectorBlock, // thread function name
ArgsDataArray[i], // argument to thread function
0, // use default creation flags
&ThreadIdArray[i]); // returns the thread identifier
if (hThreadArray[i] == NULL)
{
ret = EXIT_FAILURE;
}
sector_offset += sectors_per_thread;
}
} // End of main thread creation loop.
// Wait until all threads have terminated.
DWORD result = WaitForMultipleObjects(MAX_Threads, hThreadArray, TRUE, INFINITE);
// Free all the dynamically allocated structures
}
}
return ret;
}
【问题讨论】:
-
太宽泛了。分析您的代码,识别热点,然后优化它们。但首先检查您的设备是否确实可以以更高的速率传输。
-
是的,与我使用此程序获得的效率相比,我的硬盘可以以更高的速度传输
-
您的意思是 2GB?不是 2TB?
-
我用于测试的卷是2GB...显然它可以是任何大小。
-
您已经回答了 我知道的事情部分下的问题
2,第一个要点。其余的只是有缺陷的逻辑。出租车不会因为你添加更多司机而跑得更快。
标签: c multithreading winapi