digitalmars.D.learn - can I force a parallel foreach to finish?
- McAnany, Charles E (20/20) Jul 22 2011 SGksIGFsbC4gU28gSSdtIGdldHRpbmcgdGhlIGNsYXNzaWMgImNvbmN1cnJlbmN5IG5vb2Ii...
- Steven Schveighoffer (15/52) Jul 25 2011 I think you are misreading something, std.concurrency does not have to d...
SGksIGFsbC4gU28gSSdtIGdldHRpbmcgdGhlIGNsYXNzaWMgImNvbmN1cnJlbmN5IG5vb2IiIGJl aGF2aW9yIGZyb20gdGhpcyBjb2RlOg0KICAgIHNoYXJlZCBpbnQgdGltZXM7ICAgIA0KICAgIGlu dFtdIGl0ZXJhdGlvblJhbmdlID0gbmV3IGludFsyNTAwXTsNCiAgICBmb3JlYWNoIChwb3MsIHJl ZiAgaTsgcGFyYWxsZWwoaXRlcmF0aW9uUmFuZ2UpKXsNCiAgICAgICAgdGltZXMrKzsNCiAgICB9 DQogICAgd3JpdGVsbih0aW1lcyk7DQp9DQpQcmludHMgcmFuZG9tIG51bWJlcnMgbmVhciAxLDAw MC4NCkxvb2tpbmcgYXQgdGhlIGRvY3VtZW50YXRpb24gZm9yIHN0ZC5jb25jdXJyZW5jeSwgaXQg YXBwZWFycyB0aGF0IHdoZW4gZGVhbGluZyB3aXRoIHRhc2tzLCB5b3UgaGF2ZSB0byB5aWVsZEZv cmNlIHRvIGdldCB0aGVtIHRvIGZpbmlzaC4gSXMgdGhlcmUgYSBtZXRob2QgdGhhdCBibG9ja3Mg dW50aWwgdGFza1Bvb2wgaXRzZWxmIGlzIGVtcHR5Pw0KDQpJIHRoaW5rIHRoZSBwcm9ibGVtIGlz IG5vdCBjb25jdXJyZW50IG1vZGlmaWNhdGlvbiwgdGhlIGZvcmVhY2gganVzdCBzZWVtcyB0byBy ZXR1cm4gdG9vIGVhcmx5LCBhcyBzZWVuIGhlcmU6DQoNCmludCB0aW1lczsNCnZvaWQgc2hhcmVB dWdtZW50ZXIoKXsNCiAgICBib29sIGNvbnQgPSB0cnVlOw0KICAgIHdoaWxlKGNvbnQpew0KICAg ICAgICByZWNlaXZlKCAoaW50IGkpe3RpbWVzKys7fSwNCiAgICAgICAgICAgICAgICAgKHN0cmlu ZyBzKXt3cml0ZWZsbigiaW4gdGhlIHRocmVhZCAlcyIsdGltZXMpO2NvbnQgPSBmYWxzZTt9KTsN CiAgICB9DQp9DQp2b2lkIG1haW4oc3RyaW5nW10gYXJncyl7DQogICAgDQogICAgYXV0byB0ZCA9 IHNwYXduKCZzaGFyZUF1Z21lbnRlcik7DQogICAgaW50W10gaXRlcmF0aW9uUmFuZ2UgPSBuZXcg aW50WzI1MDBdOw0KICAgIGZvcmVhY2ggKHBvcywgcmVmICBpOyBwYXJhbGxlbChpdGVyYXRpb25S YW5nZSkpew0KICAgICAgICB0ZC5zZW5kKDEpOw0KICAgIH0NCiAgICB3cml0ZWxuKHRpbWVzKTsN CiAgICB0ZC5zZW5kKCIiKTsNCiAgICB3cml0ZWxuKHRpbWVzKTsNCnByaW50cyANCjANCjANCklu IHRoZSB0aHJlYWQgMjUwMA0KDQpDaGVlcnMsDQpDaGFybGVzLg0K
Jul 22 2011
On Fri, 22 Jul 2011 18:38:15 -0400, McAnany, Charles E <mcanance rose-hulman.edu> wrote:Hi, all. So I'm getting the classic "concurrency noob" behavior from this code: shared int times; int[] iterationRange = new int[2500]; foreach (pos, ref i; parallel(iterationRange)){ times++; } writeln(times); } Prints random numbers near 1,000. Looking at the documentation for std.concurrency, it appears that when dealing with tasks, you have to yieldForce to get them to finish. Is there a method that blocks until taskPool itself is empty?I think you are misreading something, std.concurrency does not have to do with std.parallelism Note that while compiler inserts memory barriers around operations on shared data, it does not get rid of race issues. That is, times++ is *not* atomic, so you cannot expect it to avoid races. Try: import core.atomic; atomicOp!"+="(times, 1);I think the problem is not concurrent modification, the foreach just seems to return too early, as seen here: int times; void shareAugmenter(){ bool cont = true; while(cont){ receive( (int i){times++;}, (string s){writefln("in the thread %s",times);cont = false;}); } } void main(string[] args){ auto td = spawn(&shareAugmenter); int[] iterationRange = new int[2500]; foreach (pos, ref i; parallel(iterationRange)){ td.send(1); } writeln(times); td.send(""); writeln(times); prints 0 0 In the thread 2500Note that int times is THREAD LOCAL, so essentially you have created two separate copies of times, one in the main thread and one in the sub thread. Change the declaration to: shared int times; -Steve
Jul 25 2011