1、当生产者-消费者分别由位于同一台计算机上的若干进程充当时,如何设计实验?给出设计方案和Linux C语言实现(重要语句加上注释)。
#include<stdlib.h>
#include<stdio.h>#include<string.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<sys/shm.h>
#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#define BUFFERSIZE 5//缂撳啿鍖哄ぇ灏?
//鍏变韩鍐呭瓨
struct ProductBuff {
int in ;//in鐢熶骇鑰呮寚閽?
int out;//杈撳嚭鑰呮寚閽坰hu
int buff[BUFFERSIZE];//缂撳啿鍖?
};
int semid;//淇″彿閲忛泦鍚?
int shmid;//鍏变韩鍐呭瓨
struct sembuf semaphore;//淇″彿閲?
struct ProductBuff* addr;
//PV鎿嶄綔,鐢卞弬鏁皌纭畾鏄鍝竴涓彉閲忚繘琛孭V鎿嶄綔,t=0,1,2
#define mutex 0
#define empty 1
#define full 2
void P(int t) {
semaphore.sem_num = t;
semaphore.sem_op = -1;
semaphore.sem_flg = SEM_UNDO;
semop(semid, &semaphore, 1);
}
void V(int t) {
semaphore.sem_num = t;
semaphore.sem_op = 1;
semaphore.sem_flg = SEM_UNDO;
semop(semid, &semaphore, 1);
}
void init(){
key_t semkey;//淇″彿閲忕殑鍒濆鍖?
semkey = ftok("renyuzhuo1.c", 0);
semid = semget(semkey, 3, 0666 | IPC_CREAT);
if (semid == -1) {
puts("鍒涘缓sem鍑洪敊\n");
exit(1);
}
int sem = 1;
semctl(semid, mutex, SETVAL, sem);
sem = BUFFERSIZE;
semctl(semid, empty, SETVAL, sem);
sem = 0;
semctl(semid, full, SETVAL, sem);
//鍒涘缓鍏变韩鍐呭瓨 骞舵槧灏?
key_t shmkey;
shmkey = ftok("renyuzhuo2.c", 0);
shmid = shmget(shmkey, 2048, 0666 | IPC_CREAT);
if (shmid == -1) {
printf("鍒涘缓shm鍑洪敊\n\n");
exit(1);
}
//鎶婂叡浜唴瀛樺尯瀵硅薄鏄犲皠鍒拌皟鐢ㄨ繘绋嬬殑鍦板潃绌洪棿
addr = (struct ProductBuff*) shmat(shmid, 0, 0);
if (addr == (struct ProductBuff * ) - 1) {
printf("绯荤粺鍑洪敊\n");
exit(1);
}
addr -> in = addr -> out = 0;
printf("init success!!\n");
}
//閿€姣佸叡浜唴瀛?淇″彿閲?
void destroy()
{
shmdt(addr);
printf("鏂紑鍏变韩鍐呭瓨\n");
shmctl(shmid, IPC_RMID, NULL);
printf("鍒犻櫎鍏变韩鍐呭瓨\n");
semctl(semid, IPC_RMID, 0);
printf("鍒犻櫎淇″彿閲廫n");
}
#define many 3//鐢熶骇鑰呮秷璐硅€呮暟鐩?
#define times 9//姣忎釜鐢熶骇鑰呯敓浜т骇鍝佷釜鏁?娑堣垂鑰呮秷璐逛骇鍝佷釜鏁癵e
int main() {
init();
int f, i;
//鍒涘缓杩涚▼,涓や釜杩涚▼鏄敓浜ц€咃紝涓や釜杩涚▼鏄秷璐硅€?
for (i = 0; i < many; i++) {
f = fork();
//娑堣垂鑰?
if (f > 0) {
int t = times;
while (t--)
{
P(full);//鎶㈠埌浜у搧鏉ユ秷璐?
P(mutex); //閿佷綇缂撳啿鍖?
int value = 0;
value = addr -> buff[addr -> out]; //鍙栧嚭浜у搧
addr -> buff[addr -> out] = 0;//鍙栧嚭浜у搧鍚庤浣嶇疆璁句负鍒濆鍊?
addr -> out = (addr -> out + 1) % BUFFERSIZE;//娑堣垂鑰呮寚閽堝悗绉?
printf("娑堣垂鑰呰繘绋?d鍙栬蛋鐨勪骇鍝佸€间负锛?d\n", getpid(), value);//鏄剧ず鍙栧嚭鐨勪骇鍝佺殑鍊?
int i;
printf("缂撳啿鍖哄悇鍗曞厓鐨勫€?:\t");//鏄剧ず浜у搧缂撳啿鍖轰腑鐨勫€?
for (i = 0; i < BUFFERSIZE; i++)
printf("%d\t", addr -> buff[i]);
printf("\n");
//缂撳啿鍖洪噴鏀鹃攣
V(mutex);
//缂撳啿鍖虹┖浣嶇疆鍔犱竴
V(empty);
}
}else{
//鐢熶骇鑰?
if (f == 0) {
int t = times;
while (t--)
{
P(empty);//鎶㈠埌绌轰綅缃敓浜т骇鍝?
P(mutex);//閿佷綇缂撳啿鍖?
int value = getpid();
addr -> buff[addr -> in ] = value;//灏嗕骇鍝佹斁鍏ョ紦鍐插尯
addr -> in = (addr -> in +1) % BUFFERSIZE; //鐢熶骇鑰呮寚閽堝悗绉?
printf("鐢熶骇鑰呰繘绋?d鍐欏叆缂撳啿鍖虹殑鍊?%d\n",//鏄剧ず浜у搧 value, value);
int i;
printf("缂撳啿鍖哄悇鍗曞厓鐨勫€?:\t");//鏄剧ず缂撳啿鍖虹殑鍊?
for (i = 0; i < BUFFERSIZE; i++) printf("%d\t", addr -> buff[i]);
printf("\n");
V(mutex);//閲婃斁閿?
V(full);//浜у搧鏁板姞涓€
}
}
}
}
sleep(3);
destroy();
sleep(3);
}
编译命令:
gcc 1-1.c -o 1-1 -lpthread
运行命令:
./1-1