\documentclass{ictlab} \RCS $Revision: 1.1 $ \usepackage{alltt,key,color,answer2,float} \usepackage[nolineno,noindent]{lgrind} %\usepackage[leftnum,lineno5,noindent]{lgrind} \ifx\pdftexversion\undefined \else \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref} \fi \renewcommand*{\subject}{Operating Systems and Systems Integration} \newcommand*{\labTitle}{Processes and Threads in Windows} \definecolor{light-blue}{rgb}{0.4,0.4,1} \newcommand*{\gl}[1]{\textcolor{light-blue}{#1}} % good link \newcommand*{\ex}[1]{\textcolor{green}{#1}} % executable file \newcommand*{\bl}[1]{\colorbox{red}{\textcolor{white}{\textbf{#1}}}} % bad link \renewcommand{\floatpagefraction}{0.75} % default is .5, to increase % density. \renewcommand*{\bottomfraction}{0.6} % default is 0.3 \renewcommand*{\topfraction}{0.85} % default is 0.7 \renewcommand*{\textfraction}{0.1} % default is 0.2 \setlength{\extrarowheight}{1pt} \floatstyle{ruled} \floatname{program}{Program} \newfloat{program}{tbh}{lop} \begin{document} \section{Generic Procedure for Creating Win32 Console Applications} \label{sec:generic-instructions} \begin{enumerate} \item In Windows, open the Visual \Cpp \IDE (Start $\to$ Programs $\to$ Microsoft Visual Studio 6.0 $\to$ Microsoft Visual \Cpp 6.0) \item Open a new Win32 \emph{Console} Application project (File $\to$ New $\to$ Project $\to$ Win32 Console Application). Note that you need to do this \emph{for each of the three applications}. \item Specify a project name (i.e., ``print'', ``callprint'' or ``threads'') \item Click on the ``Empty Project'' radio button, click the various confirmation buttons (\key{Finish}, \key{OK}, etc., etc.,\ldots) \item Select Project $\to$ Add to Project $\to$ Files \item Enter the name of your source file \item Compile and link your program with Build $\to$ Build \meta{project name}.exe \item Execute it with Build $\to$ Execute \meta{project name}.exe \item Note that for \texttt{print.c}, you should create a project name that matches the directory in the program file \texttt{win-call-print.c}, so that \texttt{win-call-print.c} can find \texttt{print.exe}. \item Note that the ``normal'' place to put your source code for each project is \texttt{C:\bs{}Program Files\bs{}Microsoft Visual Studio\bs{}MyProjects\bs\meta{project name}} \item The software will put the executable program in \texttt{C:\bs{}Program Files\bs{}Microsoft Visual Studio\bs{}MyProjects\bs\meta{project name}\bs{}Debug} \item Note that the \IDE executes the program in the directory \emph{above} the \texttt{Debug} directory, i.e., above where it puts the executable. This is important when executing program~\vref{prg:win-call-print}. \end{enumerate} \section{Procedure} \label{sec:procedure} \begin{program} %\smallskip% \vspace*{-2ex} %[ #include #include int main( int argc, char *argv[] ) { // argv[0] is the program name int num = atoi( argv[1] ); int loops = atoi( argv[2] ); int i; for ( i = 0; i < loops; ++i ) printf( "%d ", num ); } %] \caption{The program \texttt{print.c}. This is identical to the program \texttt{print.c} that you experimented with in your last lab.} \label{prg:print} \end{program} \begin{program} %\smallskip% \vspace*{-2ex} %[ #include #include void main() { STARTUPINFO si; PROCESS_INFORMATION pi; memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); if ( ! CreateProcess( NULL, "..\\print\\Debug\\print.exe 5 100", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi ) ) { fprintf( stderr, "CreateProcess failed with %d\n", GetLastError() ); exit( 1 ); } WaitForSingleObject( pi.hProcess, INFINITE ); CloseHandle( pi.hProcess ); CloseHandle( pi.hThread ); } %] \caption{The program \texttt{win-call-print.c}. This is like the program \texttt{call-print.c} that you experimented with in your last lab.} \label{prg:win-call-print} \end{program} \begin{program} %\smallskip% %\begin{verbatim} \vspace*{-2ex} %[ #include #include #include #define NUM_THREADS 5 DWORD WINAPI print_hello( void *threadid ) { printf( "\n%d: Hello World!\n", threadid ); return 0; } int main() { static DWORD threads[ NUM_THREADS ]; static HANDLE handles[ NUM_THREADS ]; unsigned int t; for ( t = 0; t < NUM_THREADS; ++t ) { printf( "Creating thread %d\n", t ); handles[ t ] = CreateThread( NULL, 0, ( LPTHREAD_START_ROUTINE ) print_hello, ( LPVOID ) t, 0, (LPDWORD) &threads[ t ] ); if ( ! handles[ t ] ) { printf( "Error: failed to create process %d\n", t ); exit( 1 ); } } WaitForMultipleObjects( NUM_THREADS, handles, 1, INFINITE ); return 0; } %] \vspace*{-3ex} %\end{verbatim} \caption{A simple program \texttt{win-hello.c} that works like the program \texttt{hello.c} given in the lecture. We assume that it executes in a directory at the same level as the source code, not in the \texttt{Debug} directory.} \label{prg:win-hello} \end{program} \begin{enumerate} \item Download the source code for each of these programs from the subject web site. \item For each of program~\ref{prg:print}, \ref{prg:win-call-print} and \vref{prg:win-hello}, compile and run them, using the generic instructions given in section~\vref{sec:generic-instructions}. \item Modify program~\ref{prg:win-call-print} so that it creates two processes, both running the program \texttt{print.c}. \item See if you can modify a copy of program \ref{prg:win-call-print} so that you can start \texttt{notepad.exe}. \item Modify \texttt{win-hello.c}, increasing the number of threads until you find the maximum number of threads that your system can support. \item The first student who could give me the way to compile any of these programs on the command line in Windows 2000, including all the command line parameters to the compiler, was awarded a prize of \$50 HK\e. The name of the winner is Wendell Lam: his work is shown on the subject web page. %% \begin{explanation} %% Note: it is ``cheating'' to copy system header files or system %% libraries to different locations; to do this, you will need to add %% two directories to the \texttt{PATH}, and add options to \texttt{cl} that %% include \texttt{/I}\meta{include path} and %% \texttt{/L}\meta{library path}, among other options. One of the %% directories to add to the \texttt{PATH} is \texttt{C:\bs{}Program Files\bs{}Microsoft Visual %% Studio\bs{}VC98\bs{}Bin}\e. You may find %% it easier to use the option Project $\to$ Export Makefile (or mabe %% not \texttt{:-)}. You may find it easier to use Visual Studio %% .NET (or maybe not \texttt{:-)}. %% \end{explanation} \end{enumerate} \end{document}