Multithreading Reference

Passing object by reference and Multithreading

while (true) {
std::thread t1(thread_task, b);
t1.join();
}

Two things you need to know here:

  • Use std::ref to pass a reference.
  • Infinite loop is Undefined Behavior in C++;

Working Example below:

#include <iostream>
#include <thread>

class Exmaple {
private:
int counter;

public:
Exmaple() {
counter = 0;
}

void doSomthing(){
counter++;
}

void print() {
std::cout << "value from A: " << counter << std::endl;
}

};

// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}

int main()
{
Exmaple b;
for(int i =0; i < 10; i++) {
std::thread t1(thread_task, std::ref(b));
t1.join();
}
return 0;
}

Output:

value from A: 1
value from A: 2
value from A: 3
value from A: 4
value from A: 5
value from A: 6
value from A: 7
value from A: 8
value from A: 9
value from A: 10

See it Live.

Though going further you should also consider data race

Changing a Java List Reference While Another Thread Reads It

If you mean will there be a runtime exception, the answer is no. The code that iterates over strings will use whatever the reference happens to be when the iterator invokes.

It doesn't matter if the strings reference changes while iterating. Think of it like this,

Iterator<String> i = strings.iterator();
strings = new List<String>();
while (i.hasNext()) {
...
i.next();
}

This code is fine. The object pointed to by strings hasn't changed. We only changed the strings reference to point to somewhere else. The iterator still points to the original object referenced by strings before the assignment.

EDIT: some comments below have said the original example is unsafe publication. I don't believe it is. Unsafe publication is about allowing thread B to access an object under construction in thread A- thread A is unsafely publishing the object to thread B.

However, in the example above, there's no object construction with regard to the fields in question. As far as we know both the lists were fully constructed in a thread-safe manner. There is only reference assignment. Object assignment in Java is atomic From the Java language spec,

"When a thread uses the value of a variable,
the value it obtains is in fact a value stored into the variable by
that thread or by some other thread. This is true even if the program
does not contain code for proper synchronization. For example, if two
threads store references to different objects into the same reference
value, the variable will subsequently contain a reference to one
object or the other, not a reference to some other object or a
corrupted reference value. (There is a special exception for long and
double values; see §17.4.)

Now, there might be unsafe publication in the OP's code if the object passed to updateList() wasn't constructed safely, but I'm not going to hypothesize what bugs might exist in code I can't see.

Multithreading reference?

Good reference for reading:

Thread Management In The CLR

Round-Robin Access To The ThreadPool

Multithreading with C#

Why are thread safe collections so hard?

Threading in C#

Jeffrey Richter’s Power Threading Library

Implementing a Thread-Safe Queue using Condition Variables

Threading Building Blocks.org!

Sutter’s Mill - Effective Concurrency: Understanding Parallel Performance

Sutter’s Mill - Effective Concurrency: Use Threads Correctly = Isolation + Asynchronous Messages

Thread Synchronization (C# Programming Guide)

How to synchronize access to a shared resource in a multithreading environment by using Visual C#

Use Threads Correctly = Isolation + Asynchronous Messages

Parallel and Multi-Core Computing with C/C++

Thinking in Concurrently in .NET

Programming the Thread Pool in the .NET Framework

Visual Basic .NET: Tracing, Logging, and Threading Made Easy with .NET

Juice Up Your App with the Power of Hyper-Threading

Concurrency Hazards - Solving 11 Likely Problems In Your Multithreaded Code

INFO: Descriptions and Workings of OLE Threading Models - COM STA MTA

C# Threading

Thread Synchronization (C# Programming Guide)

Overview of concurrency in .NET Framework 3.5

Multi-threading in .NET: Introduction and suggestions

Oracle - Multithreaded Programming Guide

Multithreading Tutorial

64-Bit Programming with Visual C++

How to: Create and Terminate Threads (C# Programming Guide)

Java Multithreading - Local Object References shared or not?

In this test HashSet usage is thread safe because the only reference to it is in a local variable and if another thread enters this method it will create a new Set.

void x() {
Set s = new HashSet();
s.add(1);
}

but if we save reference to our HashSet in a field then another thread may change it concurrently

Set s;

void x() {
s = new HashSet();
s.add(1);
}

void y() {
s.add(2);
}

C++: Multi threading and reference counting

Make the reference counting atomic and you won't need any lock. In Windows ::InterlockedIncrement and ::InterlockedDecrement can be used. In C++ 0x, you have atomic<>.

java: Passing a class reference to another thread

I changed your example code into what I consider to be a more meaningful example.

Communication between threads is usually handled through shared data (or channels like pipes, sockets - but I wont go there...). And while it is perfectly alright to have this shared data contained within the thread classes I have seperated the shared data from the data/methods used to administer the threads.

I hope this helps you to understand the relationship between threads and data objects.

public class TestThreads {
public static void main(String[] args)
{
DataShare ds = new DataShare();
B b = new B(ds);
A a = new A(100, ds);

b.start();
a.start();

try {
a.join(); // Waiting for A to die
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println ("Accumulated total from B = " + b.getTotal());
b.endThread();
}
}

public class DataShare {
private int value;

public DataShare () {
value = -1;
}

public synchronized boolean setValue(int val) {
boolean valueSet = false;
if (value == -1) {
value = val;
valueSet = true;
}
return valueSet;
}

public synchronized int getValue() {
int val = value;
value = -1;
return val;
}
}

public class A extends Thread {
private int max;
private DataShare dataShare;

public A (int n, DataShare ds) {
max = n;
dataShare = ds;
}

public void run() {
int i = 0;
while (i < max) {
if (dataShare.setValue(i)) {
i++;
}
}
}
}

public class B extends Thread {
private int total;
private DataShare dataShare;
private boolean running = false;

public B (DataShare ds) {
dataShare = ds;
total = 0;
}

public void run() {
running = true;
while (running) {
int nextValue = dataShare.getValue();
if (nextValue != -1) {
total += nextValue;
}
}
}

public int getTotal() {
return total;
}

public synchronized void endThread() {
running = false;
}
}

I am aware that this naive example is far from optimal since both threads are wasting precious cycles while waiting for the value to be set/read. I just wanted to keep the example as simple as possible while still addressing the point I'm trying to make.

Passing by reference to a thread C#?

Instead of using ref here, you should use an observable collection, like ObservableCollection<T>. List<string> is already pass-by-reference :)

First, change the type of clientDiscovery.OtherInstances to ObservableCollection<string>, then change the parameter type of the constructor to ObservableCollection<string> as well. Remove all the refs, you don't need those.

Now, rewrite ManageConnections to this signature (You'll need using System.Collections.Specialized):

private void ManageConnections(object sender, NotifyCollectionChangedEventArgs e) {

}

Here, you will check e.NewItems to see which items have been added to the instanceAddresses list, and add each of them to another list:

foreach (var item in e.NewItems) {
Channel channel = new Channel(item, ChannelCredentials.Insecure);
var client = new ConfigurationDirectoryService.ConfigurationDirectoryServiceClient(channel);
Instances.Add(client);
}

You might want to do something if the there are removed items as well. If you want to handle that, use e.OldItems. Those are the removed items.

Now, instead of calling ManageConnections, you do:

instancesToAdd.CollectionChanged += ManageConnections;

Note that this won't handle the initial items in the list (only subsequent changes will be added), so you might want to handle the initial items straight after the line above.

Python: threading.Thread, are values passed by value or reference?

I would say, passing mutable objects to functions is calling by reference.

You are not alone in wanting to say that, but thinking that way limits your ability to communicate with others about how Python programs actually work.

Consider the following Python fragment:

a = [1, 2, 3]
b = a
foobar(a)
if not b is a:
print('Impossible!')

If Python was a "pass-by-reference" programming language, then the foobar(a) call could cause this program to print Impossible! by changing local variable a to refer to some different object.

But, Python does not do pass-by-reference. It only does pass-by-value, and that means there is no definition of foobar that could make the fragment execute the print call. The foobar function can mutate the object to which local variable a refers, but it has no ability to modify a itself.

See https://en.wikipedia.org/wiki/Evaluation_strategy



Related Topics



Leave a reply



Submit