Consumer

Producer

Race Condition


Mutual Exclusion - If process Pi is executing in its critical section, then no other processes can be executing in their critical sections.
Progress - If no process is executing in its critical section and there exist some processes that wish to enter their critical section, then the selection of the processes that will enter the critical section next cannot be postponed indefinitely.
flag[i] = true implies that process Pi is ready!

Solution using test_and_set()

Bounded-waiting Mutual Exclusion with test_and_set




簡報網址:https://shouzo.github.io/collections/clubs/20170427-club-inheritance.pdf
SlideShare:https://www.slideshare.net/danny200026/20170427-75453393
[畫面預覽]

Message passing may be either blocking or non-blocking
Blocking send has the sender block until the message is receivedBlocking receive has the receiver block until a message is availableNon-blocking send has the sender send the message and continueNon-blocking receive has the receiver receive a valid message or nullshm_fd = shm_open(name, O CREAT | O RDRW, 0666);ftruncate(shm fd, 4096);sprintf(shared memory, "Writing to shared memory");msg_send(), msg_receive(), msg_rpc()port_allocate()advanced local procedure call (LPC) facility
connection port object.communication ports and returns the handle to one of them to the client.IP address and port – a number included at start of message packet to differentiate network services on a host
127.0.0.1 (loopback) to refer to system on which process is runningBig-endian and little-endianexactly once rather than at most once

client 部份/* vim: ts=4 sw=4 et
*/
/* The second program is the producer and allows us to enter data for consumers.
It's very similar to shm1.c and looks like this. */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "shm_com.h"
int main()
{
int running = 1;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
char buffer[BUFSIZ];
int shmid;
int rand_arr[10];
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X\n", (unsigned int)(long)shared_memory);
shared_stuff = (struct shared_use_st *)shared_memory;
while (1) {
while (shared_stuff->written_by_you == 1) {
sleep(1);
printf("waiting for client...\n");
}
/*
printf("\nPress Enter to continue...");
while (getchar() != '\n');
// fgets(buffer, BUFSIZ, stdin);
*/
srand((unsigned)time(NULL));
for (int i = 0; i < 10; i++) {
rand_arr[i] = rand() % 100 + 1;
shared_stuff->some_text[i] = rand_arr[i];
printf("[%d]%d \t", i, rand_arr[i]);
}
printf("\n");
// strncpy(shared_stuff->some_text, &rand_arr, TEXT_SZ);
shared_stuff->written_by_you = 1;
break;
}
if (shmdt(shared_memory) == -1) {
fprintf(stderr, "shmdt failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
server 部份/* vim: ts=4 sw=4 et
*/
/* Our first program is a consumer. After the headers the shared memory segment
(the size of our shared memory structure) is created with a call to shmget,
with the IPC_CREAT bit specified. */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include "shm_com.h"
int main()
{
int running = 1;
void *shared_memory = (void *)0;
struct shared_use_st *shared_stuff;
int shmid;
srand((unsigned int)getpid());
shmid = shmget((key_t)1234, sizeof(struct shared_use_st), 0666 | IPC_CREAT);
if (shmid == -1) {
fprintf(stderr, "shmget failed\n");
exit(EXIT_FAILURE);
}
/* We now make the shared memory accessible to the program. */
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1) {
fprintf(stderr, "shmat failed\n");
exit(EXIT_FAILURE);
}
printf("Memory attached at %X\n", (unsigned int)(long)shared_memory);
/* The next portion of the program assigns the shared_memory segment to shared_stuff,
which then prints out any text in written_by_you. The loop continues until end is found
in written_by_you. The call to sleep forces the consumer to sit in its critical section,
which makes the producer wait. */
shared_stuff = (struct shared_use_st *)shared_memory;
shared_stuff->written_by_you = 0;
while (1) {
if (shared_stuff->written_by_you) {
printf("\nYou wrote:\n");
for (int i = 0; i < 10; i++) {
printf("[%d]%d \t", i, shared_stuff->some_text[i]);
}
printf("\n");
sleep(rand() % 4); /* make the other process wait for us ! */
// shared_stuff->written_by_you = 0;
shared_stuff->written_by_you = 0;
}
}
/* Lastly, the shared memory is detached and then deleted. */
if (shmdt(shared_memory) == -1) {
fprintf(stderr, "shmdt failed\n");
exit(EXIT_FAILURE);
}
if (shmctl(shmid, IPC_RMID, 0) == -1) {
fprintf(stderr, "shmctl(IPC_RMID) failed\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}

