...

View Full Version : Linux Semaphore



chiefbutz
11-20-2008, 11:37 PM
I am working on an exercise for a Linux programming class I am taking, I am having some trouble. I have 2 semaphores inside a memory segment and when the second semaphore is initialized I get a seg fault. Here is the file and the header. Any help would be appreciated.

master.cpp:

#include "msg.h"
#include <cstdio>

#include <ctime>

#include <fcntl.h>

#include <iostream>

#include <istream>

#include <mqueue.h>

#include <semaphore.h>

#include <signal.h>

#include <sstream>

#include <stdlib.h>

#include <string>

#include <sys/ipc.h>

#include <sys/mman.h>

#include <sys/msg.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>
using namespace std;

// I hate to do it, but i need to...
mqd_t mq_id;
string mq_name, shm_name, srvstr;
msg srvmsg;

//
bool mainLoop(int sig);
void ouch(int sig);
//
int main(int argc, char *argv[])
{
// Vars and Such
srvmsg.type = SRVMSG;
mq_name = "/jb373-MQ";
shm_name = "/jb373-MSEG";

bool done = false;
// Setup
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0);

// Message Queue
struct mq_attr attr;
attr.mq_flags = 0;
attr.mq_maxmsg = 1;
attr.mq_msgsize = sizeof(srvmsg);
mq_id = mq_open(mq_name.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600, &attr);

// Shared Memory
int mfd = shm_open(shm_name.c_str(), O_RDWR | O_CREAT, 0600);
ftruncate(mfd, sizeof(struct memseg));
// Map the file to a shared memory segment
struct memseg* shared_memory = (struct memseg*)mmap(0, sizeof(struct memseg),
PROT_READ | PROT_WRITE, MAP_SHARED,
mfd, 0);
// We can close the file descriptor.
close(mfd);
// Semaphores
cout << "trying to init semaphores\n";
try
{
if(sem_init(((struct memseg*)&shared_memory)->r_to_u, 1, 0) != 0)
{
cout << "Sem init error\n";
}
// \/\/\/\/\/\/\/\/\/\/ PROBLEM CAUSER
if(sem_init(((struct memseg*)&shared_memory)->u_to_r, 1, 0) != 0)
{
cout << "Sem init error\n";
}
}
catch(...)
{
cout << "semaphore got mad!\n";
}
cout << "done initing semaphores\n";
// Run reverse
int pid = fork();
if(pid == 0)
{
execl("reverse", "reverse", mq_name.c_str(), shm_name.c_str(), 0);
exit(0);
}
// Run Upper
int pid2 = fork();
if(pid2 == 0)
{
execl("upper", "upper", shm_name.c_str(), 0);
exit(0);
}
// Main Loop
while(!done)
{
done = mainLoop(0);
}
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
}

bool mainLoop(int sig)
{
char str[MAXLEN];
cout << " >";
// Get the string
cin.getline(str, MAXLEN);
srvstr = str;
// Setup the string for sending
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
// Send the string
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
if(srvstr.find("-END-") != string::npos)
{
cout << "Exiting...\n";
//done = true;
return true;
}
else
return false;
}

void ouch(int sig)
{
cout << endl;
// Tells reverse to shutdown
srvstr = "-END-";
srvstr += '\0';
srvstr.copy(srvmsg.data,MAXLEN-1);
srvmsg.data[MAXLEN-1] = '\0';
mq_send(mq_id, (const char *)&srvmsg, sizeof(srvmsg), 1);
// Closing Stuff
mq_close(mq_id);
mq_unlink(mq_name.c_str());
shm_unlink(shm_name.c_str());
exit(0);
}

msg.h:

#include <semaphore.h>
const int MAXLEN = 256;

enum msgtype { SRVMSG=1, CLIMSG };

struct msg { long type; char data[MAXLEN];};

struct memseg
{
sem_t *r_to_u;
sem_t *u_to_r;
char data[MAXLEN]; // when doing stuff make sure the end is \0
};

chiefbutz
11-23-2008, 04:35 PM
Can anyone help?

Spookster
11-27-2008, 04:59 AM
Have you first tried running this through a debugger? A debugger is an invaluable tool for finding bugs. Run it through a debugger and step through the code until you get to the seg fault. In most cases the problem should become very obvious by what you see in the debugger. Since you are writing this in C++ and compiling on Linux what are you using for your compiler? Is there a specific reason you are doing this in C++? Working with shared memory and semaphores is much less complex in C since C++ has no standard wrapper for shared memory calls.

chiefbutz
12-03-2008, 12:18 AM
This is for an assignment in a class, so we need to use C++. As for my complier I am using g++. Also, I have run it through a debugger and the only thing I can see if that the semaphores aren't getting assigned memory addresses, which is probably the problem.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum