MUP1+Øvelse+5.1

toc =Inter-thread communication using System V IPC message queues in Linux I=

Opgave1+2
Når man skal sende via System V IPC skal data pakkes ind i en struct hvor det første felt er en long int type, og det næste er det du gerne vil sende. I her tilfælde skal jeg sende en struct (POINT3D) som indeholder 3 varialber. Så jeg skal have en struct i en struct. Når man sender skal man angive størrelsen på det man gerne vil sende men det er ikke størrelsen på den struct som data er pakket ind i men blot størrelsen på det data du vil sende. code format="cpp"
 * 1) include 
 * 2) include
 * 3) include
 * 4) include 
 * 5) include 
 * 6) include 
 * 7) include 

struct POINT3D { int x,y,z; };

struct MSG { long int type; POINT3D data; };

key_t key;

void* receiver(void* foo) {	POINT3D buf3D; while (1) {		msgrcv(key, (void*) &buf3D, sizeof(buf3D), 0, 0); printf("Received %i, %i, %i\n", buf3D.x, buf3D.y, buf3D.z); }	return 0; }

void* sender(void* foo) {	POINT3D point3D = { 0,0,0 }; while (point3D.x < 10) {		msgsnd(key, (void*) &point3D, sizeof(point3D), 0); point3D.x++; point3D.y++; point3D.z++; sleep(1); }	return 0; }

int main {	key = msgget((key_t) 100, 0666 | IPC_CREAT); pthread_t send, recv; pthread_create(&send, NULL, sender, NULL); pthread_create(&recv, NULL, receiver, NULL); void* ret; pthread_join(send, &ret); msgctl(key, IPC_RMID, NULL); // clean up (destory queue) return 0; } code Man skal huske at nedlægge køen når man er færdig ellers vil der være gammel data i køen næste gang man skal bruge den.

Output: code Received 1, 1, 1 Received 2, 2, 2 Received 3, 3, 3 Received 4, 4, 4 Received 5, 5, 5 Received 6, 6, 6 Received 7, 7, 7 Received 8, 8, 8 Received 9, 9, 9 code Det virker!

Opgave 3
Vi skal lave en template messages wrapper klasse. Fordi vi er trætte af at lave container klasser til vores data :) Den er således ud: code format="cpp" template class MsgWrapper { public:	long int type;	Msg data; }; code Det er meget vigtigt at type er den første variable, ellers virker det ikke.

Opgave 4
Nu skal vi lave en template sender funktion som gør brug af vores wrapper. code format="cpp" // Precondition: msgQId is the ID of a valid message queue // Postcondition: The contents of ‘data’ has been sent to the message queue // identified by msgQId template ssize_t sendMsg(int msgQId, const Msg& data) {	MsgWrapper msg; msg.type = 1; msg.data = data; return msgsnd(msgQId, (void*) &msg, sizeof(data), 0); } code Husk igen at det er størrelsen på det der skal sendes og ikke størrelsen på wrapper klassen.

Opgave 5
Nu skal vi lave en template receiver funktion som gør brug af vores wrapper. code format="cpp" template ssize_t receiveMsg(int msgQId, Msg& data) {	MsgWrapper msg; ssize_t recvSize = msgrcv(msgQId, (void*) &msg, sizeof(data), 0, 0); data = msg.data; return recvSize; } code Vi skal huske at gemme de data vi modtager i vores wrapper klasse før vi kan "pakke" det ud og sende det videre ned gennem systemet.

Opgave 6
Nu skal vi flyttet vores funktioner ud i en ny fil for at "rydde" lidt op.

code format="cpp"
 * MessageHandling.h**
 * 1) include "MsgWrapper.h"

class MessageHandling { public: template static ssize_t sendMsg(int msgQId, const Msg& data) {		MsgWrapper msg; msg.type = 1; msg.data = data; return msgsnd(msgQId, (void*) &msg, sizeof(data), 0); }	template static ssize_t receiveMsg(int msgQId, Msg& data) {		MsgWrapper msg; ssize_t recvSize = msgrcv(msgQId, (void*) &msg, sizeof(data), 0, 0); data = msg.data; return recvSize; } }; code

code format="cpp"
 * Main**
 * 1) include 
 * 2) include
 * 3) include
 * 4) include 
 * 5) include <sys/msg.h>
 * 6) include <sys/ipc.h>
 * 7) include <pthread.h>
 * 8) include "MessageHandling.h"

key_t key;

struct POINT3D { int x,y,z; };

void* receiver(void* foo) {	POINT3D buf3D; while (1) {		MessageHandling::receiveMsg<POINT3D>(key, buf3D); printf("Received %i, %i, %i\n", buf3D.x, buf3D.y, buf3D.z); }	return 0; }

void* sender(void* foo) {	POINT3D point3D = { 0,0,0 }; while (point3D.x < 10) {		MessageHandling::sendMsg<POINT3D>(key, point3D); point3D.x++; point3D.y++; point3D.z++; sleep(1); }	return 0; }

int main {	key = msgget((key_t) 100, 0666 | IPC_CREAT); pthread_t send, recv; pthread_create(&send, NULL, sender, NULL); pthread_create(&recv, NULL, receiver, NULL); void* ret; pthread_join(send, &ret); msgctl(key, IPC_RMID, NULL); // clean up	return 0; } code Som det kan ses så bliver det en del nemmere at læse.

=Hvad har vi lært?= Vi har lært at bruge message queues til at send og modtage data mellem tråde.