sem_close()?
| (1) | _____ |
A signal is said to be pending: |
|
||
| (2) | _____ |
A signal may have which of the following dispositions? |
|
||
| (3) | _____ |
A function is reentrant if: |
|
||
| (4) | _____ |
When a pipe/FIFO is empty: |
|
||
| (5) | _____ |
sem_post(): |
|
||
| (6) | _____ |
Which of the following are shared by all of the threads in a process? |
|
| (1) | _____ |
Interrupt handlers can be interrupted by signals |
| (2) | _____ |
Pipes/FIFOs guarantee writes (up to a certain size) are atomic |
| (3) | _____ |
Threads are often preferred to processes because they are easier to use with signals |
| (4) | _____ |
To avoid wasting resources, one must either call pthread_join() or pthread_detach() for every thread |
| (5) | _____ |
All thread-safe functions are reentrant |
volatile int should = 0;
static void
sighandler(int sig)
{
should = 1;
}
int
main(void)
{
float rate, sales, tax;
int status;
pid_t pid;
rate = 0.05;
pid = fork();
signal(SIGUSR1, sighandler);
switch(pid)
{
case -1:
exit(1);
case 0:
if (should_tax())
{
// Add your code here
}
break;
default:
sales = total_sales();
wait(&status);
if (should) tax = sales * rate;
else tax = 0.0;
printf("Tax: %5.2f\n", tax);
break;
}
}
wait()?
waitpid() in this case?
total_sales() is 100.00?
should_tax() returns "true", this program is
supposed to print Tax: 5.00. What will be printed if
you replace the line // Add your code here with
should = 1? Why?
//Add your code here with one or
more statements that will make the program work correctly.
Task 1 before
it prints Task 2.
static void
handle_continue(int sig)
{
// Nothing to do
}
int
main(void)
{
// Setup the signal handler
signal(SIGCONT, handle_continue);
pid_t pid = fork();
switch(pid)
{
case -1:
exit(1);
case 0:
printf("Task 1\n");
kill(getppid(), SIGCONT);
exit(0);
default:
pause();
printf("Task 2\n");
exit(0);
}
}
pause()?
pause() return?
int
main(void)
{
char msg[20];
int fd_pipe[2];
int n, status;
pid_t pid;
pipe(fd_pipe);
pid = fork();
switch(pid)
{
case -1:
exit(1);
case 0:
close(fd_pipe[1]);
read(fd_pipe[0], msg, 20);
close(fd_pipe[0]);
write(STDOUT_FILENO, msg, 20);
exit(0);
default:
close(fd_pipe[0]);
write(fd_pipe[1], "Because I said so!\n\0", 20);
close(fd_pipe[1]);
wait(&status);
exit(0);
}
}
close(fd_pipe[1]) before the call to read()?
close(fd_pipe[0]) after the call to read()?
fd_pipe contain two elements? In
other words, what are the two elements used for?
close(fd_pipe[1]) before the parent process
executes write(fd_pipe[1], "Because I said so!\n\0", 20),
will the call to write() fail? Why or why not?
int
main(void)
{
pid_t pid = fork();
switch(pid)
{
case -1:
exit(1);
case 0:
write(STDOUT_FILENO, "A1 ", 3);
write(STDOUT_FILENO, "A2 ", 3);
exit(0);
default:
write(STDOUT_FILENO, "B1 ", 3);
write(STDOUT_FILENO, "B2 ", 3);
exit(0);
}
}
static void
*count(void *arg)
{
char *s;
void *result;
s = (char *)arg;
result = (void *)(strlen(s));
return result;
}
int
main(void)
{
char *s;
int i;
long len;
pthread_t helper[5];
void *result;
s = "James Madison University";
len = strlen(s);
for (i=0; i<5; i++)
{
pthread_create(&helper[i], NULL, count, s+(i*2));
}
for (i=0; i<5; i++)
{
pthread_join(helper[i], &result);
len += (long)result;
}
printf("Characters printed: %ld\n", len);
exit(0);
}
pthread_detach() rather than
pthread_join()?
int count;
static void
*thread_entry(void *arg)
{
count += 5;
return NULL;
}
int
main(void)
{
pthread_t thread1;
count = 10;
printf("Before: %d\n", count);
pthread_create(&thread1, NULL, code_for_thread1, NULL);
pthread_join(thread1, NULL);
printf("After: %d\n", count);
exit(0);
}
static volatile int global_counter = 0;
static void*
counter(void *arg)
{
int i, limit, local_counter;
limit = *((int *) arg);
for (i=0; i<limit; i++)
{
local_counter = global_counter;
++local_counter;
global_counter = local_counter;
}
return NULL;
}
int
main(int argc, char *argv[])
{
int limit;
pthread_t thread_a, thread_b;
if (argc <= 1) limit = 100;
else limit = atoi(argv[1]);
// Start two threads counting
pthread_create(&thread_a, NULL, counter, &limit);
pthread_create(&thread_b, NULL, counter, &limit);
// Wait for both threads to terminate
pthread_join(thread_a, NULL);
pthread_join(thread_b, NULL);
// Display the result
printf("Expected: %d\n", limit*2);
printf("Actual: %d\n", global_counter);
exit(0);
}
but contains a defect known as a read-modify-write condition (a particular
kind of race condition). Use one or more pthread_mutex_t
variables to eliminate this defect.
static int should = -1; // Shared variable
static void
*thread_entry(void *arg)
{
if (should_tax()) should = 1;
else should = 0;
record_status(); // This takes a long time
return NULL;
}
int
main(void)
{
float rate, sales, tax;
pthread_t helper;
void *result;
pthread_create(&helper, NULL, thread_entry, NULL);
rate = 0.05;
sales = total_sales();
if (should) tax = sales * rate;
else tax = 0.0;
printf("Tax: %5.2f\n", tax);
pthread_join(helper, &result);
exit(0);
}
Specifically, the main thread may use the shared variable
named should before the helper thread assigns a value to it.
pthread_mutex_t variable and polling.
pthread_cond_t
variable.
Copyright 2017