纤程和线程里面按程序调用函数有什么区别?

baidu_28726667 2020-07-01 10:27:08
#include <Windows.h>
#include <strsafe.h>
#include <tchar.h>


#define PRIMARY_FIBER 0
#define WRITE_FIBER 1
#define READ_FIBER 2
#define FIBER_COUNT 3
#define COPY_LENGTH 512

VOID CALLBACK ReadFiber(LPVOID lpParam);
VOID CALLBACK WriteFiber(LPVOID lpParam);

typedef struct _tagFIBER_STRUCT
{
DWORD dwFiberHandle;
HANDLE hFile;
LPVOID lpParam;
}FIBER_STRUCT, *LPFIBER_STRUCT;

char *g_lpBuffer = NULL;
LPVOID g_lpFiber[FIBER_COUNT] = {};
void GetApp(LPTSTR lpPath, int nBufLen)
{
TCHAR szBuf[MAX_PATH] = _T("");
GetModuleFileName(NULL, szBuf, MAX_PATH);

int nLen = _tcslen(szBuf);
for (int i = nLen; i > 0; i--)
{
if (szBuf[i] == '\\')
{
szBuf[i + 1] = _T('\0');
break;
}
}

nLen = _tcslen(szBuf) + 1;
int nCopyLen = min(nLen, nBufLen);
StringCchCopy(lpPath, nCopyLen, szBuf);
}

int _tmain(int argc, _TCHAR* argv[])
{
g_lpBuffer = (char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, COPY_LENGTH);
FIBER_STRUCT fs[FIBER_COUNT] = { 0 };

TCHAR szDestPath[MAX_PATH] = _T("");
TCHAR szSrcPath[MAX_PATH] = _T("");
GetApp(szDestPath, MAX_PATH);
GetApp(szSrcPath, MAX_PATH);
StringCchCat(szSrcPath, MAX_PATH, _T("2.jpg"));
StringCchCat(szDestPath, MAX_PATH, _T("2_Cpy.jpg"));

HANDLE hSrcFile = CreateFile(szSrcPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
HANDLE hDestFile = CreateFile(szDestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);

fs[PRIMARY_FIBER].hFile = INVALID_HANDLE_VALUE;
fs[PRIMARY_FIBER].lpParam = NULL;
fs[PRIMARY_FIBER].dwFiberHandle = 0x00001234;

fs[WRITE_FIBER].hFile = hDestFile;
fs[WRITE_FIBER].lpParam = NULL;
fs[WRITE_FIBER].dwFiberHandle = 0x12345678;

fs[READ_FIBER].hFile = hSrcFile;
fs[READ_FIBER].dwFiberHandle = 0x78563412;
fs[READ_FIBER].lpParam = NULL;

g_lpFiber[PRIMARY_FIBER] = ConvertThreadToFiber(&fs[PRIMARY_FIBER]);
g_lpFiber[READ_FIBER] = CreateFiber(0, (LPFIBER_START_ROUTINE)ReadFiber, &fs[READ_FIBER]);
g_lpFiber[WRITE_FIBER] = CreateFiber(0, (LPFIBER_START_ROUTINE)WriteFiber, &fs[WRITE_FIBER]);

//切换到读纤程
SwitchToFiber(g_lpFiber[READ_FIBER]);

//删除纤程
DeleteFiber(g_lpFiber[WRITE_FIBER]);
DeleteFiber(g_lpFiber[READ_FIBER]);

CloseHandle(fs[READ_FIBER].hFile);
CloseHandle(fs[WRITE_FIBER].hFile);

//变回线程
ConvertFiberToThread();
return 0;
}

VOID CALLBACK ReadFiber(LPVOID lpParam)
{
//拷贝文件
while (TRUE)
{
LPFIBER_STRUCT pFS = (LPFIBER_STRUCT)lpParam;
printf("切换到[%08x]纤程\n", pFS->dwFiberHandle);
DWORD dwReadLen = 0;
ZeroMemory(g_lpBuffer, COPY_LENGTH);
ReadFile(pFS->hFile, g_lpBuffer, COPY_LENGTH, &dwReadLen, NULL);
SwitchToFiber(g_lpFiber[WRITE_FIBER]);
if (dwReadLen < COPY_LENGTH)
{
break;
}
}

SwitchToFiber(g_lpFiber[PRIMARY_FIBER]);
}

VOID CALLBACK WriteFiber(LPVOID lpParam)
{
while (TRUE)
{
LPFIBER_STRUCT pFS = (LPFIBER_STRUCT)lpParam;
printf("切换到[%08x]纤程\n", pFS->dwFiberHandle);
DWORD dwWriteLen = 0;
WriteFile(pFS->hFile, g_lpBuffer, COPY_LENGTH, &dwWriteLen, NULL);
SwitchToFiber(g_lpFiber[READ_FIBER]);
if (dwWriteLen < COPY_LENGTH)
{
break;
}
}

SwitchToFiber(g_lpFiber[PRIMARY_FIBER]);
}


以上是网上看文章介绍的纤程例子代码:功能就是复制 文件 。https://www.cnblogs.com/lanuage/p/7725683.html

想知道这样 "读纤程” 和 "写纤程"相互调用 和 一个线程里面直接 while(1){ 判断读完没有;读函数; 写函数;)有什么区别?
...全文
523 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly4free 2020-10-23
  • 打赏
  • 举报
回复

while(1){ 判断读完没有;读函数; 写函数;)

这个是在一个线程里 按固定顺序 【判断读完没有】【读函数】【写函数】

而你看到的一堆代码,是用代码自己操作“用户级线程”,来进行多线程读/写操作,线程切换由代码控制,而不是系统负责切换。
读与写用两个线程,分别实现。

读线程里有【判断读完没有】,写线程里有【判断写完没有】。
每个线程都有【(读/写)完了切换到另外一个线程】。





(写完了一堆,发现是 7月份的贴,算了,发就发了。)
_mervyn 2020-10-22
  • 打赏
  • 举报
回复
引用 6 楼 baidu_28726667 的回复:
是的,我意思就是while(1){ 判断读完没有;读函数; 写函数;) 和 这个文章例子的纤程有什么区别?!
角度清奇。。。 这个例子的主要作用是在介绍 windows fiber相关的API的使用方法。你要从中看到的“闪光点”在于 SwitchToFiber ,它使得你有能力中断某个函数并保存现场。 你要思考的是这个能力能为你带来什么。 而不是去纠结例子的实际功能。。。 windows 的这个纤程,其实就是个有栈协程 。 帮助你实现 协程库,你可以搜索 协程(coroutine)相关知识
baidu_28726667 2020-09-02
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
线程有同步问题 ,如果 一个 线程 中 while(1){ 判断读完没有;读函数; 写函数;) 就没问题 ,如果 读函数; 写函数; 在 2个 线程 就要 同步
是的,我意思就是while(1){ 判断读完没有;读函数; 写函数;) 和 这个文章例子的纤程有什么区别?!
schlafenhamster 2020-09-01
  • 打赏
  • 举报
回复
线程有同步问题 ,如果 一个 线程 中 while(1){ 判断读完没有;读函数; 写函数;) 就没问题 ,如果 读函数; 写函数; 在 2个 线程 就要 同步
baidu_28726667 2020-08-30
  • 打赏
  • 举报
回复
引用 3 楼 Eleven的回复:
纤程需要自己去调度,程序员自己的责任;线程由内核调度,程序员无须额外的代码。
我想问的是这样调用纤程和直接调用函数有什么区别?
Eleven 2020-07-12
  • 打赏
  • 举报
回复
纤程需要自己去调度,程序员自己的责任;线程由内核调度,程序员无须额外的代码。
schlafenhamster 2020-07-10
  • 打赏
  • 举报
回复
[code=c]
void CFiberCopyDlg::OnStart()
{
// TODO: Add your control notification handler code here
//
CString prompt;
LPFIBERDATASTRUCT fs;
// allocate storage for our fiber data structures
fs = (LPFIBERDATASTRUCT)HeapAlloc(GetProcessHeap(), 0, sizeof(FIBERDATASTRUCT) * FIBER_COUNT);
if(fs == NULL)
{
prompt.Format("HeapAlloc error! (err%=lu)\n", GetLastError());
TRACE0(prompt);
return ;
}
// allocate storage for the read/write buffer
g_lpBuffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, BUFFER_SIZE);
if(g_lpBuffer == NULL)
{
prompt.Format("HeapAlloc error! (err%=lu)\n", GetLastError());
TRACE0(prompt);
return ;
}
// open the source file
fs[READ_FIBER].hFile = CreateFile("..\\REDIST.TXT",GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);

if(fs[READ_FIBER].hFile == INVALID_HANDLE_VALUE)
{
prompt.Format("HeapAlloc error! (err%=lu)\n", GetLastError());
TRACE0(prompt);
return ;
}
// open the destination file
fs[WRITE_FIBER].hFile = CreateFile("..\\REDIST_1.TXT",GENERIC_WRITE,0,
NULL, OPEN_ALWAYS , FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(fs[WRITE_FIBER].hFile == INVALID_HANDLE_VALUE)
{
prompt.Format("CreateFile error! (err=%lu)\n", GetLastError());
TRACE0(prompt);
return ;
}
// convert this thread to a fiber, to allow scheduling of other fibers
g_lpFiber[PRIMARY_FIBER] = ConvertThreadToFiber(&fs[PRIMARY_FIBER]);
if(g_lpFiber[PRIMARY_FIBER] == NULL)
{
prompt.Format("ConvertThreadToFiber failed! err=%lu\n", GetLastError());
TRACE0(prompt);
return ;
}
// Just initialize the primary fiber data structure. We don't use
// the primary fiber data structure for anything in this sample.
fs[PRIMARY_FIBER].dwParameter = 0;
fs[PRIMARY_FIBER].dwFiberResultCode = 0;
fs[PRIMARY_FIBER].hFile = INVALID_HANDLE_VALUE;
// create the Read fiber
g_lpFiber[READ_FIBER] = CreateFiber(0, ReadFiberFunc, &fs[READ_FIBER]);
if(g_lpFiber[READ_FIBER] == NULL)
{
prompt.Format("CreateFiber error! (err=%lu)\n", GetLastError());
TRACE0(prompt);
return ;
}

fs[READ_FIBER].dwParameter = 0x12345678;
// create the Write fiber
g_lpFiber[WRITE_FIBER]=CreateFiber(0, WriteFiberFunc, &fs[WRITE_FIBER]);
if(g_lpFiber[WRITE_FIBER] == NULL)
{
prompt.Format("CreateFiber error! (err=%lu)\n", GetLastError());
TRACE0(prompt);
return ;
}

fs[WRITE_FIBER].dwParameter = 0x87654321;
// switch to the read fiber
SwitchToFiber(g_lpFiber[READ_FIBER]);
// We have now been scheduled again. Display results from the read/write
// fibers
prompt.Format("ReadFileName:%s.\r\nReadFiber result = %lu.\r\nBytes Processed = %lu\r\n",
"\"..\\REDIST.TXT\"", fs[READ_FIBER].dwFiberResultCode, fs[READ_FIBER].dwBytesProcessed);
m_Edit += prompt;

prompt.Format("WriteFileName:%s.\r\nWriteFiber result = %lu.\r\nBytes Processed = %lu\r\n",
"\"..\\REDIST_1.TXT\"", fs[WRITE_FIBER].dwFiberResultCode, fs[WRITE_FIBER].dwBytesProcessed);
m_Edit += prompt;
// Delete the fibers
DeleteFiber(g_lpFiber[READ_FIBER]);
DeleteFiber(g_lpFiber[WRITE_FIBER]);
// close handles
CloseHandle(fs[READ_FIBER].hFile);
CloseHandle(fs[WRITE_FIBER].hFile);
// free allocated memory
HeapFree(GetProcessHeap(), 0, g_lpBuffer);
HeapFree(GetProcessHeap(), 0, fs);
//
UpdateData(FALSE);
}


忏程是自调度的 schedule
baidu_28726667 2020-07-09
  • 打赏
  • 举报
回复
没有人理会。。。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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