Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 4 of 4

Thread: Linux Semaphore

  1. #1
    New Coder
    Join Date
    Mar 2005
    Location
    Indiana (USA)
    Posts
    50
    Thanks
    4
    Thanked 0 Times in 0 Posts

    Linux Semaphore

    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:
    Code:
    #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:
    Code:
    #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
    };
    Last edited by chiefbutz; 11-21-2008 at 12:41 AM. Reason: Marked where the problem causer was

  • #2
    New Coder
    Join Date
    Mar 2005
    Location
    Indiana (USA)
    Posts
    50
    Thanks
    4
    Thanked 0 Times in 0 Posts
    Can anyone help?

  • #3
    Supreme Overlord Spookster's Avatar
    Join Date
    May 2002
    Location
    Marion, IA USA
    Posts
    6,280
    Thanks
    4
    Thanked 83 Times in 82 Posts
    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.
    Spookster
    CodingForums Supreme Overlord
    All Hail Spookster

  • #4
    New Coder
    Join Date
    Mar 2005
    Location
    Indiana (USA)
    Posts
    50
    Thanks
    4
    Thanked 0 Times in 0 Posts
    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.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •