2

I have been looking at the following working code for executing code as a pthread in c++:

void * PrintHello(void * blank) { 
    cout << "Hello World" << endl
}
...
pthread_create(&mpthread, NULL, PrintHello, NULL);

I would like to know why I need to use a void * method instead of void method and also the same with the parameter. Why do they need to be pointers and what is the difference in the case of this void method and void arguement.

Mat
  • 202,337
  • 40
  • 393
  • 406
Nick Horne
  • 213
  • 3
  • 10
  • 1
    You are not using any sorts of methods here. C has no methods. –  May 24 '13 at 09:20
  • 2
    @H2CO3 Method, function, flummy, just different names for the same thing. – Daniel Fischer May 24 '13 at 09:34
  • 1
    @DanielFischer Doesn't "method" name a "member function" in OOP? (As far as I know, not even the C++ standard uses the term method, rather member function.) –  May 24 '13 at 09:36
  • 1
    @H2CO3 We're not bound to OOP terminology, and that isn't quite uniform either. Javans used to (maybe still do) call all their functions "methods", some were "instance methods", others "class methods". At least in the beginning, part of the reason for religiously avoiding the term "function" was the feeling that OOP was inherently superior to old-fashioned procedural programming (I'm afraid OOP has not yet lost enough of its newness to thoroughly have destroyed that belief, it's better for some tasks, worse for others). Doesn't change the fact that they are all _functions_. – Daniel Fischer May 24 '13 at 09:43
  • @DanielFischer Quite right. "the reason for religiously avoiding the term "function" was the feeling that OOP was inherently superior to old-fashioned procedural programming" - maybe yes, but I didn't intend to support that religion, sorry if it sounded like that. –  May 24 '13 at 09:44
  • 1
    @H2CO3 No worry, you didn't sound like that. I just strongly feel it's quite pointless to insist on a difference in terminology, unless there is one specified in the relevant standards. – Daniel Fischer May 24 '13 at 09:47
  • @DanielFischer +1 Nitpicking is nice only when done in the right place where such terminological differences makes sense. – legends2k May 24 '13 at 11:59

1 Answers1

1

You need to use a method that takes void* because it's called by pthread library, and pthread library passes your method a void* - the same pointer that you pass pthread_create as the last parameter.

Here is an example of how you can pass arbitrary parameters to a thread using a single void*:

struct my_args {
    char *name;
    int times;
};

struct my_ret {
    int len;
    int count;
};

void * PrintHello(void *arg) { 
    my_args *a = (my_args*)arg;
    for (int i = 0 ; i != a->times ; i++) {
        cout << "Hello " << a->name << endl;
    }
    my_ret *ret = new my_ret;
    ret->len = strlen(a->name);
    ret->count = strlen(a->name) * a->times;
    // If the start_routine returns, the effect is as if there was
    // an implicit call to pthread_exit() using the return value
    // of start_routine as the exit status:
    return ret;
}
...
my_args a = {"Peter", 5};
pthread_create(&mpthread, NULL, PrintHello, &a);
...
void *res;
pthread_join(mpthread, &res);
my_ret *ret = (my_ret*)(*res);
cout << ret->len << " " << ret->count << endl;
delete ret;

Even though your function does not want to take any arguments or return anything, since pthread library passes it parameters and collects its return value, your function needs to have the appropriate signature. Passing a pointer to a void function that takes no parameters in place of a void* function that takes one parameter would be undefined behavior.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Why is the return type `void*`? – Peter Wood May 24 '13 at 09:25
  • 1
    @PeterWood That's so that your threads could return data to the callers as well (through `pthread_join`). – Sergey Kalinichenko May 24 '13 at 09:30
  • yes, that's what I thought the main question was about. – Peter Wood May 24 '13 at 09:40
  • Ok, so the void* is used as a generic pointer so that any arguement can be passed in through pthread_create. I still dont understand why the void * is used as a return type if I dont want to return anything. If i returned an int from this method, how would I use the return value? – Nick Horne May 24 '13 at 09:44
  • @NickHorne Take a look at the updated example and the explanation of why you need both the arg and the return type even though you are not planning to use any of them. – Sergey Kalinichenko May 24 '13 at 09:56
  • Thank You, I saw you updated the example before your comment here and accepted it. – Nick Horne May 24 '13 at 10:01