/*****************************************************************************
*
* notepadkiller.c
*
* This program kills a running instance of Notepad somewhere on the same
* system. If no instances of Notepad are running, nothing happens.
* Technically it just sends a WM_QUIT message to some window that happens
* to have the class "Notepad", so the message could go to someplace other
* than the ubiquitous Notepad application.
*
*****************************************************************************/
#include <windows.h>
int main() {
PostMessage(FindWindow("Notepad", 0), WM_QUIT, 0, 0);
}
/*****************************************************************************
*
* butler.cpp
*
* An application in which the user clicks on the window area to "open a
* door" by pulsing the event with interprocess name "FrontDoor". This
* program creates the event; other processes can wait on it.
*
*****************************************************************************/
#include <windows.h>
// An auto-reset, initially unsignalled, event
HANDLE frontDoor = CreateEvent(0, 0, 0, "FrontDoor");
LRESULT APIENTRY WndProc(HWND hwnd, UINT msgId, WPARAM wParam, LPARAM lParam) {
switch (msgId) {
case WM_LBUTTONDOWN:
PulseEvent(frontDoor);
return 0;
case WM_DESTROY:
CloseHandle(frontDoor);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, msgId, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE currentInstance, HINSTANCE previousInstance,
LPSTR commandLine, int showState) {
char* className = "Hello";
WNDCLASS thisClass;
thisClass.style = CS_HREDRAW | CS_VREDRAW;
thisClass.lpfnWndProc = WndProc;
thisClass.cbClsExtra = 0;
thisClass.cbWndExtra = 0;
thisClass.hInstance = currentInstance;
thisClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
thisClass.hCursor = LoadCursor(NULL, IDC_ARROW);
thisClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
thisClass.lpszMenuName = NULL;
thisClass.lpszClassName = className;
RegisterClass(&thisClass);
HWND mainWindow = CreateWindow(className,
"Click inside the window to open the door", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, currentInstance, NULL);
ShowWindow(mainWindow, showState);
UpdateWindow(mainWindow);
MSG message;
while (GetMessage(&message, NULL, 0, 0) > 0) {
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
/*****************************************************************************
*
* guest.cpp
*
* This is a simple console program. It simulates a guest that wants to
* enter a friend's house. The friend's house is supposed to be simulated
* in a completely different program. This other program creates a Win API
* event called "FrontDoor". The program in this file waits on that event.
* The other program will signal the event at some time; this signal will
* relase the program here from waiting.
*
*****************************************************************************/
#include <windows.h>
#include <iostream>
int main() {
HANDLE frontdoor = OpenEvent(EVENT_ALL_ACCESS, FALSE, "FrontDoor");
if (!frontdoor) {
std::cout << "I'm supposed to be a guest trying to visit a friend.\n";
std::cout << "But the process that creates my friend and her house\n";
std::cout << "is not running on this system.\n";
return -1;
}
std::cout << "I'm waiting for the front door to be opened...\n";
WaitForSingleObject(frontdoor, INFINITE);
std::cout << "Yay! I got in.\n";
CloseHandle(frontdoor);
return 0;
}
package edu.lmu.cs.demos.threads;
/**
* This class simulates Win API AutoReset Events.
*
* An AutoResetEvent is an event object whose state, when set, remains
* signaled until a single waiting thread is released, at which time the
* state automatically gets reset to nonsignaled. If no threads are
* waiting, the event object’s state remains signaled.
*
* TODO: This implementation doesn't work if other threads call
* Object.wait() on an event object. All threads have to call
* MyEvent.waitOnEvent().
*/
public class MyEvent {
private boolean signaled;
/**
* Constructs an event. The caller determines the initial state.
*/
public MyEvent(boolean initiallySignaled) {
signaled = initiallySignaled;
}
/**
* Sets the event to signaled and, if any threads are waiting on
* the event, releases one of them causing the event object to
* revert to being non-signaled. If no threads are waiting, the
* object remains signaled.
*/
public synchronized void setEvent() {
signaled = true;
notify();
}
/**
* Resets the event (to the non-signaled state).
*/
public synchronized void resetEvent() {
signaled = false;
}
/**
* Release one waiting thread if there is one waiting, then
* immediately set the signaled state to false (whether or not
* a thread was released). We have to implement this in such a
* way that signaled will be false after the pulse. Certainly
* calling notify() will release a thread then set the signal
* to false, because of the way I wrote waitOnEvent(). But if we
* implement this method as nothing more than a single call to
* notify(), then we would have a problem in the case where the
* signal was already set because the signaled state would not
* get reset to false after the call, since that only happens when
* threads are released. So we explicitly set signaled to false if
* it was initially true.
*/
public synchronized void pulseEvent() {
if (!signaled) {
notify();
} else {
signaled = false;
}
}
/**
* Waits for the event to be signaled.
*/
public synchronized void waitOnEvent() {
while (!signaled) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Once a thread is released in an auto-reset event, it resets the
// event's state to non-signaled.
signaled = false;
}
}
One could use EnterCriticalSection to pick up and LeaveCriticalSection to put down. The only limitation of critical sections would be that a philosopher could not wait on both chopsticks at the same time, but my program doesn't do that. Mutexes can also be shared between processes, but my program is only a single process so that doesn't matter either. Critical sections are way, way faster anyway. Perhaps the only real difference is that the program might behave a little differently in the case where a philosopher dies while holding a chopstick, but who cares about that?
/*****************************************************************************
*
* priority31.cpp
*
* This program launches a thread at priority level 31 which does nothing
* but busy waits for 30 seconds.
*
*****************************************************************************/
#include <windows.h>
int main() {
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
DWORD startTime = GetTickCount();
while (GetTickCount() < startTime + 30000)
;
return 0;
}
I have a two-processor Windows box at home, and running the program seemed to have no effect on the computer's operation. The Windows Task Manager showed that one of the CPU was fully maxed. When I ran two copies of the program at the same time the UI completely froze until one of the processes finished. The task manager's animation of the CPU Usage History and Page File Usage History completely stopped as well. This was awesome.
package edu.lmu.cs.demos.threads;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* A multithreaded TCP/IP server running on port 9850 which accepts
* requests from clients for the first n digits of pi, and tries to
* oblige by sending back as many digits as it can within a fixed
* maximum duration. It logs simple messages to System.out. TODO:
* WTF is it writing to System.out for? Replace this digusting code
* with calls to a properly configured logger.
*/
public class PiServer {
private static class Handler implements Runnable, PiSpigot.Consumer {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private int digitsSent = 0;
public Handler(Socket socket) {
this.socket = socket;
}
public void run() {
try {
// Set up streams
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Read request
out.println("Welcome");
String request = in.readLine();
if (request == null) {
System.out.println("Client closed connection w/o request");
return;
}
int digitsRequested = -1;
// Validate request
try {
digitsRequested = Integer.parseInt(request);
} catch (NumberFormatException ignoredForNow) {
}
if (digitsRequested <= 0) {
out.println("A positive integer in the range 1.."
+ Integer.MAX_VALUE + " is required");
return;
}
// If request legal, send back digits for at most 30 seconds
long startTime = System.currentTimeMillis();
new PiSpigot(this, digitsRequested, startTime + 30000);
out.println();
System.out.println("Sent " + digitsSent + " digits in "
+ (System.currentTimeMillis() - startTime) + "ms");
} catch (IOException e) {
e.printStackTrace(System.out);
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace(System.out);
}
}
}
/**
* Sends a digit to the client, and flushes the output stream
* if the number of digits send so far is a multiple of 1000.
*/
public void consume(int digit) {
out.print(digit);
if (++digitsSent % 100 == 0) {
out.flush();
}
}
}
/**
* Runs the server as an application, creating a thread pool and a server
* socket and dispatching requests to threads in the pool.
*/
public static void main(String[] args) throws Exception {
System.out.println("The pi server is running");
ExecutorService pool = Executors.newFixedThreadPool(20);
ServerSocket listener = new ServerSocket(9850);
try {
while (true) {
pool.execute(new Handler(listener.accept()));
}
} finally {
listener.close();
pool.shutdownNow();
}
}
}
package edu.lmu.cs.demos.threads;
import java.util.Arrays;
/**
* A generator for the digits of pi, using the algorithm from the
* April 1995 issue of Math Monthly. Based on a Java port by Robert
* Simms(http://www.math.clemson.edu/~rsimms/neat/math/pi/piRadix.java).
* I refactored the code by pulling out the inline output and replacing
* it with calls to a listener. I also got rid of useless casts,
* and added the ability to stop after a certain time was reached.
*
* <p>This spigot delivers digits in the sequence beginning with
* 0314159, where the first digit is in the tens-place, the second
* in the ones-place, the third in the tenths-place, and so on.
* Requests for n digits will actually deliver n+3 callbacks;
* the idea being the first two are to the left of the decimal point
* anyway, and the last enables you to round off the last digit
* you wanted. Clients can take care of the quirks as they desire.
*/
public class PiSpigot {
/**
* A consumer for the digits generated by the spigot.
*/
public static interface Consumer {
void consume(int digit);
}
/**
* Creates a spigot an immediately sets it running. Uses an algorithm
* that is simple to write but very memory intensive. Don't be surprised
* by out of memory errors.
*
* @param consumer the consumer for the generated digits
* @param n the number of digits to generate
* @param stopTime the time to quit early
*/
public PiSpigot(Consumer consumer, int n, long stopTime) {
int count = -2;
int maxcount = n + 3;
int len = 10 * maxcount / 3;
int[] a = new int[len];
int digit = 0;
int nines = 0;
Arrays.fill(a, 2);
for (int j = 0; j < maxcount && count < n
&& System.currentTimeMillis() < stopTime; j++) {
int q = 0;
for (int i = len - 1; i >= 0; i--) {
int x = 10 * a[i] + q * (i + 1);
a[i] = x % (2 * i + 1);
q = x / (2 * i + 1);
}
a[0] = q % 10;
q = q / 10;
if (q == 10) {
consumer.consume(digit + 1);
for (int k = 0; k < nines; k++) {
consumer.consume(0);
}
digit = 0;
nines = 0;
} else if (q == 9) {
nines++;
} else {
consumer.consume(digit);
digit = q;
if (nines != 0) {
for (int k = 0; k < nines; k++) {
consumer.consume(9);
}
nines = 0;
}
}
}
}
}
I didn't write a client. You can test hit the server with telnet.