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-endian
exactly 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);
}