Lab 3 (5 points)
CS550, Operating Systems
Introduction to C-Style Pointers, C-Style Strings, POSIX
Threads, and Processes
Name: _____________________________________________
This assignment is based upon the UNIX labs from the CS2351 course at Oklahoma State University, previously available at cs.okstate.edu/newuser/index.html. To submit this assignment, you may copy and paste the assignment into a text editor such as nano, vi, notepad, MS Word, OpenOffice Writer, etc. Enter your answers into the document and submit it to the dropbox for lab 3. The purpose of this lesson is to learn to about command line debugging, pointers, threads, and processes in the C programming language.
1. Enter, compile, and run the following application:
#include
<stdio.h>
int main(int argc, char ** argv)
{
int arr[3] = {1,2,3};
int x = 7;
int * intPointer = &x; //This is an integer
pointer and contains the
//address of x.
printf("Welcome to C!\n");
printf("arr contains %d, %d, and %d\n", arr[0], arr[1],
arr[2]);
printf("x is %d, the address of x is %u, the address of arr
is %u\n", x, intPointer, arr);
//Notice that an integer pointer can also hold the address
of an integer array.
intPointer = arr;
printf("The address of arr is %u\n", intPointer);
//The * operator, when applied to a pointer, dereferences a
pointer or an address
intPointer = &x;
printf("Dereferencing the address of x gives its value,
which is %d\n", *intPointer);
printf("Dereferencing arr provides arr[0] which is %d\n",
*arr);
printf("Dereferencing arr+1 provides arr[1] which is %d\n",
*(arr+1));
printf("Dereferencing arr+2 provides arr[2] which is %d\n",
*(arr+2));
return
0;
}
You may type this file into the nano text editor, or copy and paste it.
PuTTY users will open PuTTY and connect to the LittleFe server as
shown in class. Log on to LittleFe and create a new file
called Welcome.c
with the nano editor. Users wishing to copy and paste the
text into nano should return to this webpage, highlight the text
of the source code, right click, and click copy. Return to
the nano editor, and right click inside the editor. The text
of the source code should now be inside the editor. Press
Ctrl-X to save and exit from nano.
Non-PuTTY users will log on to LittleFe as usual and create a new file called Welcome.c with the nano editor. Users may copy the code from this website. When inside the nano editor, right click and choose paste. The text of the source code should now be inside the editor. Press Ctrl-X to save and exit from nano.
Introduce the following errors, one at a time to the program Welcome.c. Compile the program and write down any error messages that the compiler produces. Fix the previous error message before you introduce a new error. If no errors were produced, explain why.
a. Change argc to argx.
b. Change Welcome to welcome.
c. Remove the first quote in the printf statement.
d. Remove the last quote in the printf statement.
e. Change main to mai.
f. Change printf to println.
g. Remove the semicolon at the end of the printf statement.
h. Remove the last curly bracket in the program.
i. Remove arr[0], arr[1], and arr[2] from the second printf
statement.
j. Change arr[0] to arr[4].
k. Change arr[0] to arr[50000] (this should cause a segmentation
fault).
2. Complete, compile, and run the following application. Name it Lab3.c
You may copy and paste the following code into nano while using PuTTY or another ssh client.
//
<Name>
// cs550
// Lab3
#include <stdio.h>
int main(int argc, char ** argv)
{
char str[300];
int iX;
double dX;
//Prompt the user to enter a line of text.
printf("Please enter a line of text (less than 300
characters): ");
//Use fgets to store a line of text from stdin in str.
//Prompt the user to enter an integer.
printf("Enter an integer: ");
//Use scanf to store the integer in iX.
//Prompt the user to enter a double.
printf("Please enter a real number: ");
//Use fgets and sscanf to store the double value in dX.
//Print the results.
printf("%s %d %lf\n", str, iX, dX);
return 0;
}
To create an output file, use the UNIX command script:
$script
Lab3.out
Script started, file is Lab3.out
$cat Lab3.c
<code is automatically printed here via the cat command>
$gcc Lab3.c -o Lab3.exe
$./Lab3.exe
<run the program to completion>
$exit
Script done, file is Lab3.out
Copy your file from the LittleFe system to your own system using
SFTP (the Secure File Transfer Protocol). Instructions for
an sftp client are provided at the following site:
http://catpages.nwmissouri.edu/m/monismi/cs550/examples/sftp.html
3. The following program prints hello from ten POSIX (Portable
Operating System Interface) threads. Read through the
following program and run it. Provide a copy of your output
when you submit the assignment.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 10
//Add your static array here
//Define our thread function
void * HelloThread(void * threadId)
{
long tid; // This thread's identifier
tid = (long) threadId;
//Modify the static array here
printf("Hello from thread %ld\n", tid);
pthread_exit(NULL); //Cause the thread to die.
}
int main(int argc, char ** argv)
{
pthread_t threadList[NUM_THREADS]; //Declare and
allocate memory for t$
//list of threads
int returnCode;
long i; //Counter to keep track of the current
thread
for(i = 0; i < NUM_THREADS; i++)
{
printf("From main, creating thread %ld\n",
i);
//Create the threads storing the thread
identifier in the thread
//list. Note that we pass in the name
of the function that will
//act as the thread as the third parameter,
and the following
//parameters are the parameters passed into
the thread.
returnCode =
pthread_create(&threadList[i], NULL, HelloThread,
(void *) i);
if(returnCode != 0)
{
printf("The return code from
thread %ld is %d\n", i, returnCode);
exit(-1);
}
}
//Print the static array here
//Kill the main thread
pthread_exit(NULL);
}
To compile the program above assuming it is named lab3Threads.c,
use the following command on any Linux system:
gcc lab3Threads.c -pthread -o
lab3Threads.exe
4. The following program creates ten processes and prints hello
from each of them. Read through the program and run
it. Include your output with your submission.
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define NUM_PROCESSES 10
//Declare your static array here
int main(int argc, char ** argv)
{
pid_t pid;
int i;
//Fork a child process
for(i = 0; i < NUM_PROCESSES; i++)
{
pid = fork();
if(pid < 0)
{
fprintf(stderr, "Fork failed\n");
return 1;
}
else if(pid == 0)
{
//Each child process starts here
//Modify the static array here
printf("Child %d complete!\n",
i);
exit(0);
}
else
{
//parent process
printf("Parent started process
%d\n", i);
}
}
wait(NULL);
printf("Finished parent process\n");
return 0;
}
To compile the program above, assuming it is called lab3Processes.c,
use the following command:
gcc lab3Processes.c -o lab3Processes.exe
5. Add a static integer array of size NUM_THREADS
immediately after the line containing the #define in the
thread program from problem 3. The code for this array
follows below.
static int arr[NUM_THREADS];
Set arr[(int) tid)] to a value of your choice within each
thread. Note that this value must be different for every
thread. It could be the same as the thread identifier, if
you wish.
Print the contents of this array immediately before you kill the
main thread.
Include a copy of your source code and the output in your
submission.
6. Repeat problem 5 using processes instead of threads for the
program in problem 4. Why is the output different?
Hint: think about process memory space.
7. Compile and run the following program on Stampede (Host Name:
stampede.tacc.utexas.edu ). You should be able to login to
Stampede using PuTTY and your Stampede username. Note that
you are not allowed to run your program (also called a
job) on the login node. Instructions to submit, run, check,
and, if necessary, to kill a job follow after the program.
Note that Stampede runs a variation of Linux called CentOS.
Most of the commands you used on Littlefe such as ps, ls, cat,
nano, etc., work on Stampede.
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main (int argc, char** argv)
{
int number_of_processes;
int my_rank;
int mpi_error_code;
mpi_error_code = MPI_Init(&argc, &argv);
mpi_error_code = MPI_Comm_rank(MPI_COMM_WORLD,
&my_rank);
mpi_error_code = MPI_Comm_size(MPI_COMM_WORLD,
&number_of_processes);
printf("%d o%d: Hello, world!\n", my_rank,
number_of_processes);
mpi_error_code = MPI_Finalize();
}
Save this program in a file named hello_world.c on
Stampede.
On Stampede, you must submit batch scripts to run your
programs. This means your job waits in a virtual line before
it may run. The batch queue scheduler on Stampede is called
SLURM (like the drink on Futurama). Write a SLURM batch
script for your program as follows:
#!/bin/bash
#SBATCH -A TG-SEE120004 #Account number
#SBATCH -n
16
#Number of tasks (cores)
#SBATCH -J helloWorld #Job name
#SBATCH -o hw.o%j #Output file
name
#SBATCH -p normal
#Queue to use
#SBATCH -t 00:15:00 #Run (wall) time
15min
ibrun hello_world.exe
Save this batch script in a file called hello.sbatch on
Stampede.
Compile your program on the head node using the following
command. Note that this is ok because the compilation uses
very few resources.
mpicc hello_world.c -O3 -o
hello_world.exe
Note that the executable file name matches exactly with what will
run in the batch script using ibrun.
Fix any errors in your program, and submit your program to the
batch queue using the following command:
sbatch hello.sbatch
Once your program finishes, the output will show up in a file
called hw.oJobNumber, where JobNumber is the job
number assigned to your job by Stampede. You can find this
file by using the ls command. Turn in the
contents of this file.
While your program is in the batch, run the following commands on
Stampede. If necessary, submit your program to the batch
queue again and quickly run the commands below. Note that
the up and down arrow keys can be used to scroll through
previously issued commands.
showq
What happened after running showq?
squeue -u Username
Where Username is your Stampede username. What happened
after running the command above?
Note that you may have a program that runs in an infinite loop or
enters a condition called deadlock or livelock. To end such
a program that is running on Stampede, you may first determine the
job number using squeue as shown above and killing the program
with the following command:
scancel JobNumber