类内使用CreateThread的问题

时间:2023-01-16 19:23:38
我想在类内调用一个函数,该函数单独使用一个线程类处理;但发现无法使用类内的函数,不知道大家都是怎么处理的。本人很想让这个线程和其他函数处理一样,保留类的封装性质,只能访问该对象的数据结构;

另个问题是我使用了一个静态的变量和函数,一个MyThread中创建一个线程处理,处理函数是前面的静态函数

// MyThread.h: interface for the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)
#define AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Windows.h"
#include<iostream>
using namespace std;

static int i;

static DWORD WINAPI func(LPVOID mParam)
{
i=0;
while(true)
{
Sleep(1000);
//cout<<i<<endl;
i++;
}
return 0;
}

class MyThread  
{
public:
bool BeginThread();
MyThread();
virtual ~MyThread();

private:
PROCESS_INFORMATION pi;
};

#endif // !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)

// MyThread.cpp: implementation of the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#include "MyThread.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyThread::MyThread()
{

}

MyThread::~MyThread()
{

}

bool MyThread::BeginThread()
{
unsigned long temp;
pi.hThread = CreateThread(NULL,0,func,NULL,0,&temp);
return true;
}

主函数
#include "MyThread.h"

int main()
{
MyThread m_Thread;
m_Thread.BeginThread();
while(true)
{
Sleep(1000);
cout<<i<<endl;
}
return 0;
}

但发现变量i显示的不正常,都是0;
如果直接在线程中显示是正常的;

请大家帮帮忙

23 个解决方案

#1


1、
我想在类内调用一个函数,该函数单独使用一个线程类处理;但发现无法使用类内的函数,不知道大家都是怎么处理的。
===============
全是自己写的代码,可以传this指针;
或者 用友元函数封装类函数,传友元函数地址

#2


2、>
volatile static int i;   

#3


引用楼主 cutrain2009 的回复:
 但发现变量i显示的不正常,都是0;
 如果直接在线程中显示是正常的;

 请大家帮帮忙


i 始终是0,应该是由于主线程抢占了CPU 资源,使得子线程无法运行。

另外,楼主的程序应该是个死循环吧,没有看到什么条件下程序能结束呢?

#4


使用volatile 结果是一样的,没有作用。
至于传递对象指针的,参数是在CreatThread函数中传递的,处理函数LPVOID mParam中取,但具体的实现不大清楚

#5


主,从线程是并行运行的,即使是主的死循环,从线程仍在运行的

#6


如果我在主,从线程中同时都显示i的值的话,就发现两个线程都在运行,只是从线程值在变,主线程不变

#7


引用 6 楼 cutrain2009 的回复:
如果我在主,从线程中同时都显示i的值的话,就发现两个线程都在运行,只是从线程值在变,主线程不变

请问下楼主,你的工程,应该是包括三个文件吧,比如是:MyThread.h, MyThread.cpp 及main.cpp
其中的MyThread.h 及MyThread.cpp 对应着MyThread 类的定义与实现;而main.cpp 主要是main() 函数的实现。
并且,static int i;  一句话,是包括在MyThread.h 里的。

如果确实是这么回事,那你看到的现象就很正常了。
因为static int i; 是包括在MyThread.h 里,而在main.cpp 里#include "MyThread.h" 。
实际上就使得在每个.cpp 单元文件中,都包括一个静态变量i,它们相互间是没有关系的。也即main() 里看到的i 与func() 里看到的i 不是同一个变量 。
楼主可以确认下这一点,看看两个文件中的i 的地址是否一样。

#8


确实和你描述的情况一样,请问该如何修改;

#9


可以通过参数传this指针给线程函数来操作类,调用类的相关函数

#10


不用静态变量的话,编译不过

#11


引用 8 楼 cutrain2009 的回复:
确实和你描述的情况一样,请问该如何修改;

MyThread.cpp 里:
int i;

MyThread.h 里:
extern int i;

#12


你的方法是到处变量i来使用;

我试着将处理函数和变量放在main.cpp文件中也是可以的,这样就可以解决变量的多次定义的;
但是感觉形式上有点乱;

你的方法很不错,谢啦

#13


请问能不能具体点怎么传递类对象的指针给处理函数

#14


引用 13 楼 cutrain2009 的回复:
请问能不能具体点怎么传递类对象的指针给处理函数


不太理解楼主的意思,就按我的理解这么做了:
比如:

void func(MyThread *myThread);

void main()
{
MyThread myThread;

func(&myThread);
}

#15


你这样处理的话,还是一个主线程在处理;
我试让func函数独占一个线程运行

类内接口
bool MyThread::BeginThread()
{
unsigned long temp;
pi.hThread = CreateThread(NULL,0,func,NULL,0,&temp);
return true;
}

来运行处理线程;这时候怎么给func函数传递this对象指针;

DWORD WINAPI func(LPVOID mParam)  处理函数的原型
其中mParam存的是运行参数的指针,现在该怎么处理;
和shell运行的程序一样,带有一些参数;
并且CreateThread中的第4个参数就是那个参数的指针
这是我的理解

#16


// MyThread.h: interface for the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)
#define AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Windows.h"
#include <iostream>
using namespace std;

extern int i; //声明外部变量

static DWORD WINAPI func(LPVOID mParam)
{
i=0;
while(true)
{
Sleep(1000);
//cout < <i < <endl;
i++;
}
return 0;
}

class MyThread 
{
public:
bool BeginThread();
MyThread();
virtual ~MyThread();

private:
PROCESS_INFORMATION pi;
};

#endif // !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)

// MyThread.cpp: implementation of the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#include "MyThread.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyThread::MyThread()
{

}

MyThread::~MyThread()
{

}

bool MyThread::BeginThread()
{
unsigned long temp;
pi.hThread = CreateThread(NULL,0,func,NULL,0,&temp);
return true;
}

主函数
#include "MyThread.h"
int i; //声明全局变量 i
int main()
{
MyThread m_Thread;
m_Thread.BeginThread();
while(true)
{
Sleep(1000);
cout < <i < <endl;
}
return 0;


改了i的声明,就可以了。

#17


Faint~

答得太快,没有看完题目

是的 我的第二个答案是错的

#18


谢啦,这个已经解决了,
第一个问题请问如何解决,参数的问题

#19


我就说怎么帖子回答了那么多。。。。

#20


怎么将对象的指针传给处理函数,该处理函数单独使用一个线程,

#21


传this就行了
CreateThread(NULL,
        0,
        func,     
        this,       
        0,
        &temp);

#22


恩,解决了,谢谢啦

#23


用大家的建议,我将处理函数定义为类的友元函数,这样整个类都封装了,只有一个处理函数有那么点别扭;
请问大家,这样处理有哪些不妥吗,
会出问题吗,比如我多次调用处理函数,也就是多个从线程运行,
或是MyThread有多个运行实例对象的时候

#1


1、
我想在类内调用一个函数,该函数单独使用一个线程类处理;但发现无法使用类内的函数,不知道大家都是怎么处理的。
===============
全是自己写的代码,可以传this指针;
或者 用友元函数封装类函数,传友元函数地址

#2


2、>
volatile static int i;   

#3


引用楼主 cutrain2009 的回复:
 但发现变量i显示的不正常,都是0;
 如果直接在线程中显示是正常的;

 请大家帮帮忙


i 始终是0,应该是由于主线程抢占了CPU 资源,使得子线程无法运行。

另外,楼主的程序应该是个死循环吧,没有看到什么条件下程序能结束呢?

#4


使用volatile 结果是一样的,没有作用。
至于传递对象指针的,参数是在CreatThread函数中传递的,处理函数LPVOID mParam中取,但具体的实现不大清楚

#5


主,从线程是并行运行的,即使是主的死循环,从线程仍在运行的

#6


如果我在主,从线程中同时都显示i的值的话,就发现两个线程都在运行,只是从线程值在变,主线程不变

#7


引用 6 楼 cutrain2009 的回复:
如果我在主,从线程中同时都显示i的值的话,就发现两个线程都在运行,只是从线程值在变,主线程不变

请问下楼主,你的工程,应该是包括三个文件吧,比如是:MyThread.h, MyThread.cpp 及main.cpp
其中的MyThread.h 及MyThread.cpp 对应着MyThread 类的定义与实现;而main.cpp 主要是main() 函数的实现。
并且,static int i;  一句话,是包括在MyThread.h 里的。

如果确实是这么回事,那你看到的现象就很正常了。
因为static int i; 是包括在MyThread.h 里,而在main.cpp 里#include "MyThread.h" 。
实际上就使得在每个.cpp 单元文件中,都包括一个静态变量i,它们相互间是没有关系的。也即main() 里看到的i 与func() 里看到的i 不是同一个变量 。
楼主可以确认下这一点,看看两个文件中的i 的地址是否一样。

#8


确实和你描述的情况一样,请问该如何修改;

#9


可以通过参数传this指针给线程函数来操作类,调用类的相关函数

#10


不用静态变量的话,编译不过

#11


引用 8 楼 cutrain2009 的回复:
确实和你描述的情况一样,请问该如何修改;

MyThread.cpp 里:
int i;

MyThread.h 里:
extern int i;

#12


你的方法是到处变量i来使用;

我试着将处理函数和变量放在main.cpp文件中也是可以的,这样就可以解决变量的多次定义的;
但是感觉形式上有点乱;

你的方法很不错,谢啦

#13


请问能不能具体点怎么传递类对象的指针给处理函数

#14


引用 13 楼 cutrain2009 的回复:
请问能不能具体点怎么传递类对象的指针给处理函数


不太理解楼主的意思,就按我的理解这么做了:
比如:

void func(MyThread *myThread);

void main()
{
MyThread myThread;

func(&myThread);
}

#15


你这样处理的话,还是一个主线程在处理;
我试让func函数独占一个线程运行

类内接口
bool MyThread::BeginThread()
{
unsigned long temp;
pi.hThread = CreateThread(NULL,0,func,NULL,0,&temp);
return true;
}

来运行处理线程;这时候怎么给func函数传递this对象指针;

DWORD WINAPI func(LPVOID mParam)  处理函数的原型
其中mParam存的是运行参数的指针,现在该怎么处理;
和shell运行的程序一样,带有一些参数;
并且CreateThread中的第4个参数就是那个参数的指针
这是我的理解

#16


// MyThread.h: interface for the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)
#define AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Windows.h"
#include <iostream>
using namespace std;

extern int i; //声明外部变量

static DWORD WINAPI func(LPVOID mParam)
{
i=0;
while(true)
{
Sleep(1000);
//cout < <i < <endl;
i++;
}
return 0;
}

class MyThread 
{
public:
bool BeginThread();
MyThread();
virtual ~MyThread();

private:
PROCESS_INFORMATION pi;
};

#endif // !defined(AFX_MYTHREAD_H__F33A4E09_FE1A_4D17_AE1D_C50F38C008F6__INCLUDED_)

// MyThread.cpp: implementation of the MyThread class.
//
//////////////////////////////////////////////////////////////////////

#include "MyThread.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

MyThread::MyThread()
{

}

MyThread::~MyThread()
{

}

bool MyThread::BeginThread()
{
unsigned long temp;
pi.hThread = CreateThread(NULL,0,func,NULL,0,&temp);
return true;
}

主函数
#include "MyThread.h"
int i; //声明全局变量 i
int main()
{
MyThread m_Thread;
m_Thread.BeginThread();
while(true)
{
Sleep(1000);
cout < <i < <endl;
}
return 0;


改了i的声明,就可以了。

#17


Faint~

答得太快,没有看完题目

是的 我的第二个答案是错的

#18


谢啦,这个已经解决了,
第一个问题请问如何解决,参数的问题

#19


我就说怎么帖子回答了那么多。。。。

#20


怎么将对象的指针传给处理函数,该处理函数单独使用一个线程,

#21


传this就行了
CreateThread(NULL,
        0,
        func,     
        this,       
        0,
        &temp);

#22


恩,解决了,谢谢啦

#23


用大家的建议,我将处理函数定义为类的友元函数,这样整个类都封装了,只有一个处理函数有那么点别扭;
请问大家,这样处理有哪些不妥吗,
会出问题吗,比如我多次调用处理函数,也就是多个从线程运行,
或是MyThread有多个运行实例对象的时候