进程和消息队列问题

时间:2018-04-28 23:29:57

标签: c linux

此程序用于计算给定范围内的素数(作为命令行参数给出)。我必须为此程序使用进程和消息队列。素数范围被分成相等的数据大小(每个过程处理一个单独的范围)。父进程使用消息队列将范围发送到每个子进程。每个进程都会创建许多线程来计算素数。每个进程中的主线程对素数求和,并将结果发送给父进程。

我目前陷入第193行,我正在声明线程数组。然后代码跳到父进程并基本上给出随机数。

现在这是我在Ubuntu中编译后获得的输出:

screenshot

// Linux input to run program: 
// g++ prime.cpp -o prime -lpthread -std=c++11    
// ./prime 10 60 5 2 

#include <pthread.h> 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <sys/msg.h>
#include <fstream>
#include <iostream>
#include <mutex>
#include <math.h>
#include <vector>
#include <ctype.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#define PERM (S_IRUSR | S_IWUSR)
using namespace std;

void *primecalc(void *argument); // the runner

pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; // define the mutex lock


// sets up message structure (holds what needs to be set to child process)
// min, max, etc
char cwdpath[600];


struct mystructure 
{
   long mtype;
   int num_threads;
   int min;
   int max;
   int process_id;
   int sum_primes;
};

struct threadstructure
{
   int min;
   int max;
   string filename;
};

// get the ID of the main process
int queueid;

int initqueue(int key) 
{                    /* initialize the message queue */
   queueid = msgget(key, 0666 | IPC_CREAT);
   if (queueid == -1) 
   {
       return -1;
   }
   return 0;
}

int main(int argc, char *argv[]) 
{
    if (argc !=5)
    {
        return 0;
    }


    // define the number the primes will be calculated up to
    // and define the number of threads

    // get arguments
    int numprimesmin = atoi(argv[1]);
    int numprimesmax = atoi(argv[2]);
    int num_processes = atoi(argv[3]);
    int num_threads = atoi(argv[4]);
    int error;


    // these are the leftover prime numbers
    int leftover = numprimesmax%num_processes; 
    // the interval of prime numbers that each process checks
    int range = numprimesmax/num_processes;    
    // the current minimum in each process
    int currentmin = numprimesmin;            
    // the current maximum in each process    
    int currentmax = range + currentmin;          

    // get the current working directory, and define the key
    getcwd(cwdpath, 600);
    const char *path = cwdpath;
    key_t key = ftok(path, 'd');
    initqueue(key);

    // initialize the message with beginning data
    mystructure message = {1, num_threads, currentmin, currentmax, 0, 0};

    // initialize the process
    pid_t process;

    // for each process, perform these actions
    for(int i = 0; i<num_processes; i++)
    {
        // send the messages out
        if (msgsnd(queueid, (const void*)&message, sizeof(message)-sizeof(message.mtype), 0) == -1)
        {
            error = errno;
        }

        // update the current proccesses 
        if(i != (num_processes-1))
        {
            currentmin = currentmax + 1;
            currentmax = range +currentmin; 
        }
        else // this is for the last process
        {
            currentmin = currentmax +1;
            // last process does extra work
            currentmax = leftover + currentmin + range; 
        }

        message.min = currentmin; // update min and max for the structure
        message.max = currentmax; 
    }



    //printf("Prime Numbers: \n");

    // Create the proccesss
    pid_t pid;
    for(int k = 1; k <= num_processes; k++)
    {
        pid = fork();
        if (pid == 0)
        {
            break;
        }
    }

    // this is the parent only
    if (pid > 0)
    {
        int ftotal= 0;
        while (wait(NULL)>0);
        for (int u = 0; u < num_processes; u++)
        {
        mystructure finalmessage; // initialize the final message
        msgrcv(queueid, (void*)&finalmessage, sizeof(finalmessage)-sizeof(finalmessage.mtype), 1, 0); // receive the final message 
        cout << "The sum of the prime number computed by process " << finalmessage.process_id << " is " << finalmessage.sum_primes << endl;
        ftotal += finalmessage.sum_primes; // add the sum of primes in this process to the total
        }
        // output the sum of all prime number sums
        cout << "The total of all prime numbers in this range is: " << ftotal << endl;

         return 0;

     }


    // this is the child only
    if(pid == 0)
    {

        mystructure threadmessage;
        msgrcv(queueid, (void*)&threadmessage, sizeof(threadmessage)-sizeof(threadmessage.mtype), 1, 0);

        srand (time(NULL));
        int random = rand()%10000+1;
        string name = "filething" + to_string(random);

        // get arguments
        int Cnumprimesmax = threadmessage.max;
        int Cnumprimesmin = threadmessage.min;
        int Cnum_threads = threadmessage.num_threads;

        // get ranges
        int Cleftover = Cnumprimesmax%Cnum_threads;
        int Crange = Cnumprimesmax/Cnum_threads;   // divides
        int Ccurrentmin = Cnumprimesmin;
        int Ccurrentmax = Crange + Ccurrentmin;


        threadstructure minmax;
        minmax.min = Cnumprimesmin;
        minmax.max = Cnumprimesmax;
        minmax.filename = name;
        // HERE IT IS 
        cout << " this is before the threads declaration" << endl;
        pthread_t tid[Cnum_threads];
        cout << "test after array declaration" << endl;
        for (int i = 0; i < Cnum_threads; i++)
        {
            pthread_attr_t attr; // define default attribute
            pthread_attr_init(&attr);

            cout << "test thing" << endl;
            pthread_create(&tid[i], NULL, &primecalc, &minmax);// create each thread, using the primecalc function

           if(i != (Cnum_threads-1))
           {
               Ccurrentmin = Ccurrentmax + 1;
               Ccurrentmax = Crange +Ccurrentmin; 
           }
           else // this is for the last process
           {
               Ccurrentmin = Ccurrentmax +1;
               Ccurrentmax = Cleftover + Ccurrentmin + Crange; // last process does extra work
           }

           threadmessage.min = Ccurrentmin; // update min and max for the structure
           threadmessage.max = Ccurrentmax;
           }    

           for (int i = 0; i < Cnum_threads; i++)
           {
               pthread_join(tid[i],NULL);
               cout << "test 5" << endl;
               printf("\n");
           }


           cout << "skipped it all\n";
           ifstream myfile (name.c_str());
           int number;
           int total = 0;
           while(myfile >> number)
           {
               cout << "test text" << endl;
               total += number;
           }
           myfile.close();

           mystructure finalmessage = {1, 0, 0, 0, getpid(), total};
           cout << "test 4" << endl;
           msgsnd(queueid, (const void*)&finalmessage, sizeof(finalmessage)-sizeof(finalmessage.mtype), 0);


    }

    printf("\nComplete\n");

}

//Each thread will calculate the prime numbers in the range
void *primecalc(void *argument) 
{
    cout << "test 333" << endl;
    threadstructure *variables = (threadstructure*)argument;
    cout << "test 3334" << endl;
    int i, j; // define loop variables
    cout << "test 3335" << endl;
    int lower = variables->min;
    cout << "test 333" << endl;   
    int upper = variables->max; // dereference the argument
    cout << "test 3336" << endl;
    while (lower < upper)
    {
        int trap = 0;
        for(i = 2; i <= lower/2; ++i)
        {
            if(lower % i == 0)
            {
                trap = 1;
                break;
            }
        }
        if (trap == 0)
        {
            pthread_mutex_lock(&mutex1); // set mutex lock for output
            if(trap == 0) 
            {
                ofstream myfile ((variables->filename).c_str());
                if (myfile.is_open())
                {
                    myfile << i <<endl;
                    myfile.close();
                }
                else cout << "Unable to open file";

            }           
            pthread_mutex_unlock(&mutex1); // unlock mutex for output
         }
         ++lower;
    }
    //Exit the thread
    pthread_exit(NULL);
}

0 个答案:

没有答案