www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Passing parameters to thread functions

reply "D_Starter" <gitarre fastmail.cn> writes:
Hey there,

I'm in the process of learning D, switching from C/C++ and 
Pascal. In this I've come across multithreading capabilities.

What I'm trying to achieve is to create a thread, call a thread 
function with parameters and have the thread return something. 
Like this:

[CODE]
import core.thread;

void thread_proc(ref uint var)
{
     uint v = var << 1;
     var = v;
}

int main()
{
     uint var = 7;
     auto thread1 = new Thread(&thread_proc, val).start();  /* 
similar to C++ STL */
     thread1.join();

     return 0;
}
[/CODE]

You might have guessed...this won't work. So how do I pass 
parameters to thread functions? I haven't found anything useful 
on the library description so far.

I've already learned that using shared global variables does 
work, but that's not what I want.
Aug 15 2015
next sibling parent "D_Starter" <gitarre fastmail.cn> writes:
On Saturday, 15 August 2015 at 12:22:08 UTC, D_Starter wrote:
 Hey there,

 I'm in the process of learning D, switching from C/C++ and 
 Pascal. In this I've come across multithreading capabilities.

 What I'm trying to achieve is to create a thread, call a thread 
 function with parameters and have the thread return something. 
 Like this:

 [CODE]
 import core.thread;

 void thread_proc(ref uint var)
 {
     uint v = var << 1;
     var = v;
 }

 int main()
 {
     uint var = 7;
     auto thread1 = new Thread(&thread_proc, val).start();  /* 
 similar to C++ STL */
     thread1.join();

     return 0;
 }
 [/CODE]

 You might have guessed...this won't work. So how do I pass 
 parameters to thread functions? I haven't found anything useful 
 on the library description so far.

 I've already learned that using shared global variables does 
 work, but that's not what I want.
In main() it's meant to be uint val = 7;
Aug 15 2015
prev sibling next sibling parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
In the documentation, it talks about derived threads in one of 
the examples. That's one way to do this:

import core.thread;

// Thread sub class can hold data
// we pass the params through the constructor
class MyThread : Thread {
         uint* var;
        // ref only works one level deep - it stops being ref when 
you assign it somewhere else
        // so we use a pointer instead
         this(uint* var) {
                 this.var = var;
                 super(&run);
         }
         void run() {
                 uint v = *var << 1;
                 *var = v;
         }
}
int main()
{
     uint val = 7;
     auto thread1 = new MyThread(&val).start();
     thread1.join();
     return 0;
}



You can also use a delegate inline instead of a separate function:

import core.thread;
int main()
{
     uint val = 7;
       // the inline defined {} returns a delegate which
       // Thread will accept, and it can access local vars
       // directly
     auto thread1 = new Thread({ val <<= 1; } ).start();
     thread1.join();
     return 0;
}


That delegate is the shortest code but keep in mind that val is 
now shared by the main thread and the child thread and may be 
written to by both of them at once...


Or there's also http://dlang.org/phobos/std_concurrency.html#spawn

the spawn function from std.concurrency, which is meant to give 
you functions for message passing between threads but also lets 
you start one like this:


import core.thread, std.concurrency;

void thread_proc(shared(uint)* var)
{
     uint v = *var << 1;
     *var = v;
}

int main()
{
     shared(uint) var = 7; // has to be shared tho!
     spawn(&thread_proc, &var); // pass args to it here

     thread_joinAll(); // it doesn't return the Thread object 
though... spawn returns a Tid used for send and receive messages, 
so we join differently

     return 0;
}



The big change here is the explicit shared(uint) instead of plain 
uint. core.thread lets you share stuff implicitly (which can get 
weird with two threads writing to it at the same time). 
std.concurrency requires you to be more explicit about it.
Aug 15 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Saturday, 15 August 2015 at 12:46:22 UTC, Adam D. Ruppe wrote:
 core.thread lets you share stuff implicitly (which can get 
 weird with two threads writing to it at the same time). 
 std.concurrency requires you to be more explicit about it.
Do you know whether that's intentional? The entire page on core.thread doesn't mention "shared" even once... However I found this ancient ticket [2] on dsource.org, but it's unclear whether this even refers to D2. [1] http://dlang.org/phobos/core_thread.html [2] http://www.dsource.org/projects/druntime/ticket/23
Aug 15 2015
parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 15 August 2015 at 13:20:06 UTC, Marc Schütz wrote:
 On Saturday, 15 August 2015 at 12:46:22 UTC, Adam D. Ruppe 
 wrote:
 core.thread lets you share stuff implicitly (which can get 
 weird with two threads writing to it at the same time). 
 std.concurrency requires you to be more explicit about it.
Do you know whether that's intentional? The entire page on core.thread doesn't mention "shared" even once... However I found this ancient ticket [2] on dsource.org, but it's unclear whether this even refers to D2. [1] http://dlang.org/phobos/core_thread.html [2] http://www.dsource.org/projects/druntime/ticket/23
Delegate do not come with a type qualifier for their payload, so there is no way to do otherwize.
Aug 15 2015
parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Saturday, 15 August 2015 at 23:45:29 UTC, deadalnix wrote:
 Delegate do not come with a type qualifier for their payload, 
 so there is no way to do otherwize.
Looks like they do: alias X = void delegate() const; void z(X fun) { fun(); } void main() { int a; z({ a = 42; }); } xx.d(6): Error: function xx.z (void delegate() const fun) is not callable using argument types (void delegate() pure nothrow nogc safe)
Aug 17 2015
prev sibling next sibling parent reply "anonymous" <anonymous example.com> writes:
On Saturday, 15 August 2015 at 12:22:08 UTC, D_Starter wrote:
 int main()
 {
     uint var = 7;
     auto thread1 = new Thread(&thread_proc, val).start();  /* 
 similar to C++ STL */
     thread1.join();

     return 0;
 }
 [/CODE]

 You might have guessed...this won't work. So how do I pass 
 parameters to thread functions? I haven't found anything useful 
 on the library description so far.
You can pass a delegate that calls the function: ---- uint val = 7; auto thread1 = new Thread({thread_proc(val);}).start(); ---- If you have more questions, please post them to the 'learn' group (<http://forum.dlang.org/group/learn>) and not here.
Aug 15 2015
next sibling parent "D_Starter" <gitarre fastmail.cn> writes:
 Adam and anonymous:

This looks promising. I'll give it a try :thumbsup:
Aug 15 2015
prev sibling parent "D_Starter" <gitarre fastmail.cn> writes:
 On Saturday, 15 August 2015 at 12:49:47 UTC, anonymous wrote:

 You can pass a delegate that calls the function:
 ----
 uint val = 7;
 auto thread1 = new Thread({thread_proc(val);}).start();
 ----
For the sake of simplicity this is perfectly fine and works. Data races seem possible but can be avoided with the use of distinct variables and waiting for the threads to finish.
Aug 15 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/15/2015 05:22 AM, D_Starter wrote:

 I haven't found anything useful on the library description so
 far.
In addition to the posted documentation links, I have the following chapters that may be helpful. - Message Passing Concurrency http://ddili.org/ders/d.en/concurrency.html - Data Sharing Concurrency http://ddili.org/ders/d.en/concurrency_shared.html And the following related ones: - Parallelism http://ddili.org/ders/d.en/parallelism.html - Fibers (still considered a draft) http://ddili.org/ders/d.en/fibers.html Ali
Aug 15 2015
parent "D_Starter" <gitarre fastmail.cn> writes:
On Saturday, 15 August 2015 at 22:21:34 UTC, Ali Çehreli wrote:
 On 08/15/2015 05:22 AM, D_Starter wrote:

 I haven't found anything useful on the library description so
 far.
In addition to the posted documentation links, I have the following chapters that may be helpful. - Message Passing Concurrency http://ddili.org/ders/d.en/concurrency.html - Data Sharing Concurrency http://ddili.org/ders/d.en/concurrency_shared.html And the following related ones: - Parallelism http://ddili.org/ders/d.en/parallelism.html - Fibers (still considered a draft) http://ddili.org/ders/d.en/fibers.html Ali
Thanks a lot! I'll have looked asap.
Aug 15 2015