0

I'm taking an intro to operating systems course and we're to use the clone() call in linux to create threads and then do some stuff with them. I seem to be having trouble just using clone() at all.

I've structured my code into a single class (called Homework) which is in the namespace for the class (Course). This may be the problem as this is the first time I've really used the namespace keyword. I'm trying to use the things I rarely do to become more experienced with it so if I have a dumb mistake, so be it.

I found some articles on the web but they didn't help much. I've read the man page but I guess I'm not experienced enough to understand what the problem is. One day! Thanks for any assistance :)

I want to have the method to catch the clones inside the class:

// -- Header -- //  
namespace _Course_ {  
    class _Homework_ {  
               ...  
        int threadCatch(void *);  
               ...  
   };  
}

// -- Source -- //  
namespace _Course_ {   
  void _Homework_::threadTest(void) {  
             ...  
     // From web article  
     void **childStack;  
     childStack = ( void **) malloc(KILOBYTE);  
     clone(threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL);  
             ...  
  }  

  int _Homework_::threadCatch(void * ){  
    cout << getpid() << " cloned." << endl;    
    exit(0);  
  }
}

Is what I currently have. I've tried different ways (taking the catcher out of the class, then namespace). It's compiled twice but when I try to recompiled after a make clean it tells me the function (threadCreate) is declared in multiple locations. Because of these weird errors I'm sure I'm doing something wrong and instead of hack at it I'll take some opinions. What should I do, or what should I read next? Thanks!

RedX
  • 14,749
  • 1
  • 53
  • 76
Student
  • 25
  • 3
  • 1
    You can get automatic code formatting simply by selecting your code in the question editor and clicking the "{ }" button. No need to go through and mark things as bold or italic. – Oliver Charlesworth Feb 09 '11 at 20:59
  • 1
    Mixing C++ classes and `clone` sounds like a horrible idea. Using `clone` yourself (rather than `pthread_create`) is already a bad enough idea in itself unless you're reimplementing pthreads... – R.. GitHub STOP HELPING ICE Feb 09 '11 at 21:01
  • 2
    there's no problem calling clone() from inside a C++ class, the pointer to the function is all that is needed. I agree, clone() should not be your first choice when making a threaded application, posix threads are better, and more portable. That said, I suspect that this instructor is starting with clone() and will move up to pthreads later. starting with clone gives the students a basis to understand pthreads and its advantages over clone. – Brian Onn Feb 09 '11 at 21:10
  • Indeed, clone() is required. This is just an assignment and I structured it this way for easy use, not functionality. I also didn't think something like this would come up and be such a pain. The clones wont be doing much (just logging time).Oli, thank you for the advice I didn't know that. – Student Feb 09 '11 at 21:26

2 Answers2

1

Define your catch function as a static class function.

static int threadCatch(void *);

Also (and you probably don't need this, but just in case, I'll say it here) you might also need to use the scope resolution operators to send it to clone(). I don't think so, since you're using it inside of the Homework class already. but I say it just in case, it might help you.

clone(Homework::threadCatch, childStack, CLONE_VM | CLONE_FILES, NULL);
Brian Onn
  • 1,026
  • 11
  • 18
  • Thanks! I had it as static at one point but I don't think it was inside my class. Worked (compiled). Thank you. – Student Feb 09 '11 at 21:27
  • you're welcome. Glad it helped and good luck with your course. – Brian Onn Feb 10 '11 at 18:46
  • one more thing.. if you once had it static, but outside the class, then it probably didn't work because it would have needed to be declared extern "C" as Void said. – Brian Onn Feb 10 '11 at 18:55
1

The clone(2) system call expects a pointer to a function with C linkage. Since you're using C++ I'd recommend moving your threadCatch() function into the global namespace and declare it as an extern "C" function. You could also declare the method in your class as static but I feel that making it a free function with C linkage more closely matches how the function is to be passed as a parameter.

If you need to make calls to C++ objects inside your threadCatch() function that exist outside of it's scope you can pass pointers to those objects as the arg parameter to the clone() call. Your threadCatch() function would then cast the arg to the appropriate type so that you can access your C++ object(s) accordingly.

Void - Othman
  • 3,441
  • 18
  • 18
  • This is also good advice as I'm sure when I eventually need to pass information I'll hit another wall. Thanks a bunch. – Student Feb 09 '11 at 21:29
  • +1 for extern "C" linkage. Note that it's not required in this case since he's defining it and calling it in the same compilation unit. But you are absolutely right, better to define the static function as extern "C" as expected by the clone() call. Passing arg as a pointer to a class and casting to a class is also good advice, I do it all the time inside C funcions. – Brian Onn Feb 10 '11 at 18:49