source: git/Singular/dyn_modules/systhreads/doc/primitives.md @ f0f0003

spielwiese
Last change on this file since f0f0003 was f0f0003, checked in by Reimer Behrends <behrends@…>, 5 years ago
Libthread implementation.
  • Property mode set to 100644
File size: 6.1 KB
Line 
1# Building the library
2
3Run:
4
5        ./configure && make && make install
6
7Use:
8
9        ./configure --singular=/path/to/singular
10
11instead if you want to use this with a different Singular installation.
12
13The "make install" command will install `systhreads.so` and `systhreads.lib`
14in the MOD and LIB directories.
15
16# Usage
17
18The library can be used by loading it with:
19
20        LIB "systhreads.lib";
21
22# Threads
23
24Threads can be created with `createThread()`. Once no longer in use,
25thread resources should be disposed of with `joinThread()`. It is
26possible to evaluate expressions in an interpreter with `threadEval()`
27and retrieve the result with `threadResult()`.
28
29Example:
30
31        thread t = createThread();
32        threadEval(t, quote("foo" + "bar"));
33        threadResult(t);
34        joinThread(t);
35
36If no result is needed, `threadExec(th, expr)` can be used instead, as
37can be the variants `threadExecString(th, string)` and
38`threadExecFile(th, filename)`.
39
40To load a library into a thread, `threadLoadLib(th, libname)` is available.
41
42A unique numeric per-thread id is available via `threadID()`. To check
43if the program is executing the main thread, the `mainThread()` function
44can be used; it'll return `1` for the main thread and `0` for all other
45threads.
46
47# Shared objects
48
49This library primarily provides a number of types to share data
50between threads, such as channels or atomic hash tables. We call
51instances of these types "shared objects".
52
53Shared objects can contain basic Singular values, such as integers,
54strings, lists, numbers (note: not all types of numbers are currently
55supported), rings, polynomials, and ideals (note that not all Singular
56types are supported yet). They can also contain references to other
57shared objects. When basic singular values are stored in a shared
58object, a copy of that value is created (if necessary, along with any
59ring it is based on). Shared objects that are stored in other shared
60objects are stored as references and are not copied.
61
62# Channels
63
64Channels are created via `makeChannel(uri)`. You can use
65`sendChannel(ch, val)` to send values to a channel and
66`receiveChannel(ch)` to read them from the channel.
67
68        channel ch = makeChannel("channel:example");
69        sendChannel(ch, 314);
70        receiveChannel(ch);
71
72Also, `statChannel(ch)` returns the number of elements in the channel.
73Note that this is an estimate, as new elements can concurrently be
74written to or existing elements retrieved from the channel.
75
76# Syncronization Variables
77
78Synchronization Variables are created via `makeSyncVar(uri)`. You can
79use `writeSyncVar(sv, val)` to write a value to a synchronization
80variable and `readSyncVar(sv)` to read from it. Note that writing a
81synchronization variable more than once results in an error and reading
82from a synchronization variable that has not yet been written to will
83block the underlying thread.
84
85Example:
86
87        syncvar sv = makeSyncVar("syncvar:example");
88        writeSyncVar(sv, list(1, 2, 3));
89        readSyncVar(sv);
90
91It is possible to modify the value of a syncvar after it has been
92initialized with `updateSyncVar(sv, procname, ...)`. This procedure
93updates a syncvar with the result of applying procname to its contents
94(and any additional arguments being passed in).
95
96Example:
97
98        syncvar sv = makeSyncVar("syncvar:example");
99        writeSyncVar(sv, 0);
100        proc add(int x, int y) { return (x+y); }
101        updateSyncVar(sv, "add", 1);
102        updateSyncVar(sv, "add", 2);
103
104The intended use of `updateSyncVar` is to have it store a sequence
105of monotonically increasing values (such as a sequence of integers
106or a sequence of sets where each set is a superset of its predecessor)
107until the value satisfies a condition.
108
109Like all shared objects, synchronization variables can contain
110other shared objects. This is particularly useful to make them
111globally available across all threads.
112
113Example:
114
115        syncvar channel_var = makeSyncVar("syncvar:channel");
116        writeSyncVar(channel_var, makeChannel("channel:main"));
117        channel ch = readSyncVar(channel_var);
118        sendChannel(ch, "test");
119        readChannel(ch);
120
121# Atomic Tables
122
123Atomic hash tables exist to store values that can concurrently been
124accessed by multiple threads. An atomic table is created via
125`makeAtomicTable(uri)`; it can be written to with `putTable(table, key,
126value)`, read with `getTable(table, key)`, and you can check whether
127a table holds a key with `inTable(table, key)`.
128
129Example:
130
131        atomic_table table = makeAtomicTable("table:example");
132        putTable(table, "foo", 314);
133        inTable(table, "foo");
134        inTable(table, "bar");
135        getTable(table, "foo");
136
137# Atomic Lists
138
139Atomic lists work like atomic hash tables, but are indexed by integers
140rather than strings. They are created via `makeAtomicList(uri)`, are
141written with `putList(list, index, value)`, and read with `getList(list,
142index)`. Atomic lists resize automatically if a value is entered at an
143index beyond the end of the list.
144
145Example:
146
147        atomic_list list = makeAtomicList("list:example");
148        putList(list, 3, 2718)
149        getList(list, 3);
150
151# Regions
152
153Regions are individually lockable regions of memory that can contain
154other objects, namely shared hash tables and lists. These tables and
155lists work like atomic tables and lists, but can only be accessed when
156the region is locked.
157
158Example:
159
160        region r = makeRegion("region:example");
161        lockRegion(r);
162        shared_table table = makeSharedTable(r, "table");
163        shared_list list = makeSharedList(r, "list");
164        putTable(table, "foo", 314);
165        getTable(table, "foo");
166        putList(list, 1, 2718);
167        getList(list, 1);
168        unlockRegion(r);
169
170Attempting to use list and table operations while the region is not
171locked by the current thread will result in an error.
172
173# Region locks
174
175To make management of region locking easier, there is a regionlock
176type. This can store the result of a `lockRegion(r)` call and will
177automatically unlock when it goes out of scope.
178
179Example:
180
181        proc testGlobals(region r, string key) {
182          regionlock lk = regionLock(r);
183          shared_table globals = makeSharedTable(r, "globals");
184          return(inTable(globals, key));
185        }
Note: See TracBrowser for help on using the repository browser.