Threading and P/Invoke

cavalcadejewelΛογισμικό & κατασκευή λογ/κού

18 Νοε 2013 (πριν από 4 χρόνια και 5 μήνες)

101 εμφανίσεις

Threading and

Tom Roeder

CS215 2006fa


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


More common idiom:

public void Finalize() {




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


images from MSDN

Nov 2000

IDisposable and using

Idea for common cleanup

using(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

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


Useful for large objects

infrequently accessed

nice to have but can be regenerated


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;



Can control the behavior of GC

not recommend in general

sometimes useful to give hints

Some methods:





Memory Profiles


lots of small short
lived objects

or few but long
lived ones

few links between old and new objects


frequently create long
lived objects

create many objects that live a long but fixed
amount of time

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

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

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;


Threading provides concurrent execution

Even useful on multiprocessor

As opposed to “sequential” execution

Comes at cost of overhead

Can be dangerous

For example

public int Increment(ref int x) { return ++x; }

What happens when called by two threads?

How to fix?


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


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


several others (see Birrell’s paper or MSDN)

Threading model: lock

Basic idea: each object has a lock

public 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

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?

Threading model: Monitor



enter/exit the monitor for a given object


wait on a given object

must be inside a monitor for that object

delayed semantics


some thread(s) can be released to try the monitor

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

only on Wait or Sleep

Allows cleanup of invariants

Other synchro classes


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

Threading model: ThreadPool

Instead of explicitly creating threads

create a pool

pass delegates to worker threads

enqueued in pool


takes a WaitCallback delegate

Good for large amounts of parallel work

eg. N
Body problem

automatically scales to number of processors

“embarrasingly parallel” problems

Threading Conclusions

Standard monitor semantics

as in Java

useful constructions

OS synchronization exposed

native ThreadPool

Really only need




Use special attributes to make system calls



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?

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

Calling a COM Server

namespace CallingCOMServer


using System;

using COMServerLib;

public class DotNET_COMClient


public static int Main(string[] args)


MyCOMServer myS = new MyCOMServer();

return (myS.Add (17,4));




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

to get better info


namespace 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);



.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

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

P/Invoke Example

namespace 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",




P/Invoke Callbacks

Unmanaged code can call back to managed

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

Unmanaged Code


DLL function

Callback Example

public class EnumReport


public bool Report(int hwnd, int lParam)

{ // report the window handle

Console.Write("Window handle is ");


return true;



public class SampleClass


delegate bool CallBack(int hwnd, int lParam);


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);



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