C++ linux C++;课堂上的线程

C++ linux C++;课堂上的线程,c++,linux,C++,Linux,嗨,我想做的类与方法,将开始在单独的线程创建类后。我就是这样做的: class Devemu { int VarInc; void Increm() { for(;;) { if (VarInc > 532) VarInc = 0; else VarInc++; } } public: static void* IncWrapper(void* thisPtr) { ((Devemu*) thisPtr)->Increm()

嗨,我想做的类与方法,将开始在单独的线程创建类后。我就是这样做的:

class Devemu {
int VarInc;

void Increm() {
    for(;;) {
        if (VarInc > 532) VarInc = 0;
        else VarInc++;
    }
}

public:
static void* IncWrapper(void* thisPtr) {
    ((Devemu*) thisPtr)->Increm();
    return NULL;
}
Devemu() {
    VarInc = 0;
}
int Var() {
    return VarInc;
}
};
int main(int argc, char** argv) {

Devemu* em = new Devemu();
pthread_t thread_id;
pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);


for(int i = 0 ;i < 50; i++) {
printf("%d\n", em->Var());
}
return (EXIT_SUCCESS);
}
class-Devemu{
int-VarInc;
无效增量(){
对于(;;){
如果(VarInc>532)VarInc=0;
else-VarInc++;
}
}
公众:
静态void*IncWrapper(void*thisPtr){
((Devemu*)thisPtr)->Increm();
返回NULL;
}
德维姆(){
VarInc=0;
}
int-Var(){
返回变量;
}
};
int main(int argc,字符**argv){
Devemu*em=new Devemu();
pthread_t thread_id;
pthread_create(&thread_id,NULL,&Devemu::IncWrapper,NULL);
对于(int i=0;i<50;i++){
printf(“%d\n”,em->Var());
}
返回(退出成功);
}

与在main和IncWrapper方法中创建的pthread_不同,我可以更改它吗?

是的,如果您愿意,可以将其放入构造函数中:

class Devemu {
int VarInc;
pthread_t thread_id;

void Increm() {
    for(;;) {
        if (VarInc > 532) VarInc = 0;
        else VarInc++;
    }
}

public:
static void* IncWrapper(void* thisPtr) {
    ((Devemu*) thisPtr)->Increm();
    return NULL;
}
Devemu() {
    VarInc = 0;

    pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
}
int Var() {
    return VarInc;
}
};

我认为最好将线程创建放在单独的成员函数中,如下所示:

class Devemu {

    ...

    void run()
    {
        pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
    }

    ...
};
实际上不是在ctor中,因为有时您(或使用您的代码的任何人)可以忘记在ctor中创建的线程,并开始编码,如:

Devemu m;
...
Devemu m1;
...

创建不必要的线程,就像类的实例一样。

如果您想获得可用的源代码,需要进行下一步更改:

--- so0.cpp     2019-11-04 11:26:11.101984795 +0000
+++ so1.cpp     2019-11-04 11:26:57.108501816 +0000
@@ -1,3 +1,7 @@
+#include "stdio.h"
+#include <pthread.h>
+#include <cstdlib>
+
 class Devemu {
 int VarInc;

@@ -24,7 +28,7 @@

 Devemu* em = new Devemu();
 pthread_t thread_id;
-pthread_create(&thread_id, NULL, &Devemu::IncWrapper, NULL);
+pthread_create(&thread_id, NULL, &Devemu::IncWrapper, em);
--so0.cpp 2019-11-04 11:26:11.101984795+0000
+++so1.cpp 2019-11-04 11:26:57.108501816+0000
@@ -1,3 +1,7 @@
+#包括“stdio.h”
+#包括
+#包括
+
类Devemu{
int-VarInc;
@@ -24,7 +28,7 @@
Devemu*em=new Devemu();
pthread_t thread_id;
-pthread_create(&thread_id,NULL,&Devemu::IncWrapper,NULL);
+pthread_create(&thread_id,NULL,&Devemu::IncWrapper,em);
我解决您问题的方法是:

#include "stdio.h"
#include <pthread.h>
#include <cstdlib>
#include <unistd.h>

class Devemu {
private:
    int VarInc;

    pthread_attr_t attr; /* отрибуты потока */
    pthread_t thread_id;

    void Increm();
public:
    static void* IncWrapper (void* thisPtr);
    Devemu();
    ~Devemu();
    int Var();
};

void Devemu::Increm() {
    while (true) {
        if (VarInc > 532) {  VarInc = 0; } else { VarInc++; }
    }
}

void* Devemu::IncWrapper(void* thisPtr) {
    ((Devemu*) thisPtr)->Increm();
    return NULL;
}

Devemu::~Devemu() {
    pthread_cancel (thread_id);
}

Devemu::Devemu() {
    VarInc = 0;
/// get default value of arrts
    pthread_attr_init(&attr);
/// start thread
    pthread_create(&thread_id, &attr, &Devemu::IncWrapper, this);

}

int Devemu::Var() {
    return VarInc;
}

int main(int argc, char** argv) {
    Devemu* em = new Devemu();

    for(int i = 0 ; i < 100; i++) {
        printf("%d\n", em->Var());
        usleep (10);
    }
    delete em;
    usleep (1000);
    return (EXIT_SUCCESS);
}
#包括“stdio.h”
#包括
#包括
#包括
类Devemu{
私人:
int-VarInc;
pthread_attr_t attr;/**/
pthread_t thread_id;
无效增量();
公众:
静态void*IncWrapper(void*thisPtr);
Devemu();
~Devemu();
int-Var();
};
void Devemu::Increm(){
while(true){
if(VarInc>532){VarInc=0;}else{VarInc++;}
}
}
void*Devemu::IncWrapper(void*thisPtr){
((Devemu*)thisPtr)->Increm();
返回NULL;
}
Devemu::~Devemu(){
pthread\u cancel(线程id);
}
Devemu::Devemu(){
VarInc=0;
///获取arrts的默认值
pthread_attr_init(&attr);
///起始线程
pthread_create(&thread_id,&attr,&Devemu::IncWrapper,this);
}
int-Devemu::Var(){
返回变量;
}
int main(int argc,字符**argv){
Devemu*em=new Devemu();
对于(int i=0;i<100;i++){
printf(“%d\n”,em->Var());
usleep(10);
}
删除em;
usleep(1000);
返回(退出成功);
}

奇怪的是,但我确信这是有原因的,新的C++0x线程在创建(或可以)对象的那一刻就开始运行。也就是说,没有单独的对象+“ok now run”调用。必须小心不要启动两次;)嗯……你说得对,但是如果我想只运行两个线程呢?在run()的情况下,我可以按如下方式执行:
Devemu m;m.run();…Devemu m1;m1.run()
而不更改ctor中的代码。无论如何,我更喜欢显式创建进程、线程等,而不是隐式创建。忘记这些小事情很容易,特别是当您的项目足够大时。@JDonner:@maverik建议是正确的。Boost和c++0x线程从构造开始,因为在它们的设计中有一个明确的划分,即f职责。
thread
对象只运行线程。在示例代码中,如果在构造时启动线程,则无法保证新线程在当前线程完成构造之前不会进入函数,这是未定义的行为。如果类为p,则更危险olymorphic和线程运行的函数进行多态方法调用(动态调度)。事实上,与问题中提出的设计(扩展Java线程)相比,我更喜欢C++0x设计(实现Java Runnable),因为很难进入那个特定的陷阱。谢谢它工作,但返回分段错误。我添加了mutex_lock和mutex_trylock,它也返回分段错误