threading and p/invoke tom roeder cs215 2006fa. finalization recall c++ destructors: ~myclass() { //...

33
Threading and P/Invoke Tom Roeder CS215 2006fa

Post on 21-Dec-2015

220 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading and P/Invoke

Tom Roeder

CS215 2006fa

Page 2: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Finalization

Recall C++ destructors:~MyClass() { // cleanup}

called when object is deleted does cleanup for this object

Don’t do this in C# (or Java) similar construct exists but only called on GC no guarantees when

Page 3: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Finalization

More common idiom:public void Finalize() { base.Finalize(); Dispose(false);}

maybe needed for unmanaged resources slows down GC significantly

Finalization in GC: when object with Finalize method created

add to Finalization Queue when about to be GC’ed, add to Freachable Queue

Page 4: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Finalization

images from MSDNNov 2000

Page 5: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

IDisposable and using

Idea for common cleanupusing(T t = new T()) { // do work with t} // t.Dispose is called by runtime

IDispose provides one method: void Dispose() must provide finalizer, since must be called

when called from finalizer, don’t undo managed obj often add private void Dispose(bool)

using calls Dispose automatically used in class libraries, eg. for Socket

Page 6: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Weak References

Sometimes want to keep references but not cause the GC to wait MyClass c = new MyClass();

WeakReference wr = new WeakReference(c);

Now c can be collected wr will return null if referenced after c collected but to truly access the object, we get a strong ref

this is the Target property

Why? Useful for large objects

infrequently accessed nice to have but can be regenerated

Page 7: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Resurrection

Imagine assigning this to global in finalizer object is now reachable again! called “resurrection” if finalizer already called, access unpredictable

Should not do this but, if do, may want to reject accesses in methods what would this finalize code do:

someObj = this;System.GC.ReRegisterForFinalize()

Page 8: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

System.GC

Can control the behavior of GC not recommend in general sometimes useful to give hints

Some methods: Add/RemoveMemoryPressure ReRegisterFor/SuppressFinalize WaitForPendingFinalizers Collect

Page 9: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Memory Profiles

Good lots of small short-lived objects or few but long-lived ones few links between old and new objects

Bad frequently create long-lived objects create many objects that live a long but fixed

amount of time

Page 10: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

unsafe mode

Sometimes need access to pointers use unsafe modifier:

unsafe public void Method(out int* pi) { int i = 10; fixed(int* pj = &i) { pi = pj; }}

what is wrong with this method? unsafe modifier works a method modifier

or as a keyword for blocks

Page 11: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

unsafe mode - Pointer details

Can only refer to “unmanaged” types or enums or structs composed of unmanaged types

Not a subclass of object void* exists, but no arithmetic allowed boxing/unboxing does not work stackalloc gets memory from the stack

Page 12: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

unsafe mode

Cannot be executed in untrusted context security requirement: so can’t change memory eg. avoid stack smashing attacks

pointer types cannot refer to a reference cannot refer to a struct that contains references

int* pi, pj; // NOT int *pi, *pj;

Page 13: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading

Threading provides concurrent execution Even useful on multiprocessor As opposed to “sequential” execution Comes at cost of overhead Can be dangerous

For examplepublic int Increment(ref int x) { return ++x; }

What happens when called by two threads? How to fix?

Page 14: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading

How to create a Thread Create a new Thread instance with delegate Type: public delegate void ThreadStart(); Call Start method Let’s do an example on the board

Thread will be scheduled when possible on SMP, may actually have many threads at once on UP, still may be useful when blocked

as in UI, networking code, dealing with drivers

Page 15: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading

Need synchronization primitives Way to ensure that only one thread executes

code in a region at once Called “critical section”

C# provides (mostly in System.Threading) lock statement Monitor class Interrupt several others (see Birrell’s paper or MSDN)

Page 16: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading model: lock

Basic idea: each object has a lockpublic int Increment(ref int x) {lock(this) return ++x;}

lock prevents more than one thread from entering forces sequential order

What should we lock on? for instance variables: this for globals and statics: typeof(container) something that will be same for all threads that

access this shared memory

Page 17: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading model: Monitor

Monitors provide synchronization construct entry waits on a queue waiting lets a new thread enter

Monitor.Enter and Monitor.Exit same semantics as the lock construct Why do we need both?

Gets a lock on the object Cannot be used on value types: why not?

Page 18: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading model: Monitor

Methods Monitor.Enter/Monitor.Exit

enter/exit the monitor for a given object Monitor.Wait

wait on a given object must be inside a monitor for that object signal-delayed semantics

Monitor.Pulse/Monitor.PulseAll some thread(s) can be released to try the monitor

Page 19: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading model: Interrupt

Sometimes need to wake up a thread eg. if UI cancelled eg. if event no longer needed

Standard OO way: exceptions Interrupt causes thread to throw

ThreadInterruptedException only on Wait or Sleep

Allows cleanup of invariants

Page 20: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Other synchro classes

Abort throws exception immediately difficult to clean up: Why? usually too draconian

Mutex and other synchronization good for interacting with Windows but stick with lock and Monitor, normally

ReaderWriter Locks not clear exactly what semantics they implement

Page 21: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading model: ThreadPool

Instead of explicitly creating threads create a pool pass delegates to worker threads enqueued in pool QueueUserWorkItem

takes a WaitCallback delegate

Good for large amounts of parallel work eg. N-Body problem automatically scales to number of processors “embarrasingly parallel” problems

Page 22: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Threading Conclusions

Standard monitor semantics as in Java

useful constructions OS synchronization exposed native ThreadPool

Really only need lock Monitor

Page 23: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

P/Invoke

Use special attributes to make system calls eg.

[DllImport(“kernel32”)]static extern int GetProcessHeap();

calls to function in C library problems for C++

name mangling: doesn’t match General problem of COM/.NET interop

why does this matter?

Page 24: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

COM Interoperability

Need metadata generated from TypeLib

Can then use COM class like .NET class even though major differences in models eg. threading, registration, inheritance useful for backwards compatibility

Can bind early or late to class either we know its type at compile time or not

Page 25: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Calling a COM Servernamespace CallingCOMServer{

using System;using COMServerLib;

public class DotNET_COMClient{...

public static int Main(string[] args){

MyCOMServer myS = new MyCOMServer();return (myS.Add (17,4));

}}

};

Page 26: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Late-Bound Activation

Use Reflection to get the type of the class ProgID / ClassID: looked up in registry gives type of COM object

Can instantiate instance and call methods uses InvokeMethod to call methods don’t have as strong type information here

COM object wrapped by __ComObject can sometimes use as to get better info

Page 27: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Late-Boundnamespace LateBoundClient{

using System.Reflection;...Type typ;Object obj;Object[] prms = new Object[2];int r;typ = Type.GetTypeFromProgID(„MyLib.MyServer");obj = Activator.CreateInstance(typ);prms[0] = 10; prms[1] = 150; r = (int)typ.InvokeMember(„aMethod",

BindingFlags.InvokeMethod, null, obj, prms);...

}

Page 28: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

.NET from COM

Needs to be public with public methods Need to register a wrapper: use RegAsm tool

provides ProgID/ClassID information for registry necessary for COM integration

Metadata must be converted to TypeLibrary Have same early- and late-bound activation

early: by name late: by ProgID/ClassID

Page 29: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Platform from .NET

Calling static functions in DLLs P/Invoke provides services

Locates implementing DLL Loads DLL Finds function address

Fuzzy name matching algorithm Pushes arguments on stack Performs marshalling Enables pre-emptive garbage collection Transfers control to unmanaged code

Page 30: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

P/Invoke Examplenamespace HelloWorld

{ using System;

class MyClass { [dllimport(“user32.dll”, CharSet=CharSet.Ansi)] static extern int MessageBox(int h, string m,

string c, int t); public static int Main() { return MessageBox(0, "Hello World!", "Caption", 0); } }}

Page 31: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

P/Invoke Callbacks

Unmanaged code can call back to managed code Unmanaged parameter is function pointer Must supply parameter as delegate P/Invoke creates callback thunk

Passes address of thunk as callback parameter

Managed Code

.NET Application

Call passes pointer to callback function

Implementation of callback function

Unmanaged Code

DLL

DLL function

Page 32: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Callback Examplepublic class EnumReport

{ public bool Report(int hwnd, int lParam) { // report the window handle Console.Write("Window handle is "); Console.WriteLine(hwnd); return true; }};public class SampleClass{ delegate bool CallBack(int hwnd, int lParam);

[DllImport("user32")] static extern int EnumWindows(CallBack x, int y);

public static void Main() { EnumReport er = new EnumReport(); CallBack myCallBack = new CallBack(er.Report); EnumWindows(myCallBack, 0); }}

Page 33: Threading and P/Invoke Tom Roeder CS215 2006fa. Finalization Recall C++ destructors: ~MyClass() { // cleanup } called when object is deleted does cleanup

Managed Extensions for C++

Allows C++ code to be managed by GC/CLR compile with /clr: It Just Works

generates MSIL from C++ contains, eg

__gc, __box, __typeof, __interface, __property #pragma managed/unmanaged

Very useful for native access to C++ libraries build a “managed wrapper”

Partial conversion to managed code