【问题标题】:putting an array of structs into shared memory in unix so that it can be accessed by a client program将一个结构数组放入 unix 的共享内存中,以便客户端程序可以访问它
【发布时间】:2018-01-03 13:56:24
【问题描述】:

所以我目前正在尝试使用共享内存和 fork() 函数在 unix 中进行编码,我有一个包含 10 个结构的数组,我想将该数组放入共享内存中,以便客户端可以访问它程序。我希望有人可以为我指明正确的方向。

我目前拥有的代码是:

//  Compiler Directives


//  Standard Library Inclusions
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <time.h>
//Other Inclusions

struct strProcess 
{
  int nPriority;
  int nPid;
};
//  Function Prototypes (if not included within a header file)
int frand (int nInput);
int finval (int nInput);
void fsortasc(struct strProcess pArray[],int nInput);
//  Main
int main(void)
{
// Variable Declarations
int     nShmid,i,arraySize,nRpriority,j, nInput;
key_t   nKey;
char    *ptrshm, *ptrs;
int     nSize;
pid_t   pid; 
struct  strProcess pArray[10];
struct  strProcess *Array;

Array = pArray;
// Code start

nKey = 5678;
FILE *f = fopen("logfile.txt", "w");

if (f == NULL)
{
      printf("Error opening file!\n");
      exit(1);
}

printf("please enter the amount of processes to create for this cycle between 1 and 10 \n");
scanf("%d",&nInput);
if (nInput <= 0 || nInput > 10)
{
  nInput = finval(nInput);
}
printf("%d", nInput);

nSize = sizeof(pArray) * 10;
 //create segment
if ((nShmid = shmget(nKey,nSize, IPC_CREAT | 0666)) <0)
{
      perror("shmget");
      exit(1);
}
printf("segment created \n\n");
fprintf(f, "shared memory segment created");

Array *pArray = shmat(shmid,NULL, 0);
if (Array* pArray (-1)) 
{
      perror("shmat");
      exit(1);
}
printf("segment attached \n\n");
fprintf(f, "shared memory segment attached");

for(i = 0 ; i < nInput; i++)
{
    if ((pid = fork()) < 0)
    {
      perror("fork");
      exit(1);
    }
    if (pid == 0)
    {
      Array[i].nPid = getpid();
      nRpriority = frand(nInput);
      Array[i].nPriority = nRpriority;
      printf("print job created with Pid %d and priority number %d", 
      getpid(), nRpriority);
      fprintf(f, "print job created with Pid %d and priority number %d", 
      getpid(), nRpriority);
    }
}

fprintf(f, " %d processes have been created", nInput);
fsortasc(pArray, nInput);   /*sort array into ascending order by nRpriority values*/

// Function Definitions - in alphabetical order
int finval (int nInput)
{
while(nInput <= 0 || nInput > 10)                               
{
    printf("please enter a number between 1 and 10 \n");
    scanf("%d", &nInput);                                       
} 
return nInput;                                                
}

int frand (int nInput)
{   
int nRand;
nRand = (rand() % nInput)+1;                  /*set nRand == a random number 
                                               inbetween nInput and 1*/
return nRand;                                 /*return the random number*/
}

void fsortasc(struct strProcess pArray[],int nInput)  
{
struct strProcess temp;     /*temporary storage for elements being swapped*/
int i, j;

for (i = 0; i < nInput - 1; i++)                                 
{
    for (j = 0; j < (nInput - 1-i); j++)
    {
        if (pArray[j].nPriority > pArray[j + 1].nPriority)                      /*if the current element is greater than the next element*/
        {
            temp = pArray[j];                                                   
            pArray[j] = pArray[j + 1];                                          
            pArray[j + 1] = temp;                                               
        }                                                                       
    }
}

【问题讨论】:

  • 您发布的代码是否代表您已编译的内容? (因为原样,您发布的内容没有)
  • 我的代码无法编译,我只是想弄清楚如何将数组放入我创建的共享内存中
  • 查看这个答案HERE。它有足够的细节让你开始。顺便说一句,这实际上是一个非常有用的网站,可以从人们那里获得答案,但与任何事情一样,您应该知道 rules of the road 以最大限度地提高您在这里的体验。

标签: c arrays unix struct shared-memory


【解决方案1】:

我有一个包含 10 个结构的数组,我想将该数组放入共享内存中? 很简单,首先创建 array 10 struct variable,然后使用 shmget 的创建 shared memory需要size,然后是attach,即shared memorypointer,最后是copy 10 个结构的数组,指向附加shmat 的指针。我在下面添加了简单的代码来了解您的要求。

typedef struct company {
        int emp_id;
}cmp;
int main(int argc,char *argv[]) {
        cmp cmp_info[10];
        int shm_id, sze = sizeof(cmp_info) ,i;
        /* I have an array of 10 structs -- with some data like emp_id*/
        for(i=0 ;i<10 ;i++) {
        printf("\n enter emp % Id \n",i);
        scanf("%d",&cmp_info[i].emp_id);
        }
        /* create the shared memory of 'sze' size. */
        shm_id = shmget(10,sze, IPC_CREAT | 0664);
        perror("shmget");
        /* attach the shared memory with shm_id */
        cmp *shm_ptr = shmat(shm_id, NULL, 0);
        perror("shmat");
        /* I have an array of 10 structs and I would like to put that array into shared memory  */
        shm_ptr = cmp_info;//now shared memory contains array of 10 struct data 

        /** print using shm_ptr to verify **/
        for(i=0;i<10;i++) {
        printf("Employee[%d] Id is : [%d]\n",i,shm_ptr[i].emp_id);
        }
        /* once above things are done clients program can read from shared memory */
        /** finaly de-atach the shared memory */
        shmdt(shm_ptr);
}

下面的快照是你的代码,解释在 cmets。

struct strProcess {
        int nPriority;
        int nPid;
};
int main(int argc,char *argv[]) {
        // Variable Declarations
        int     nShmid,i,arraySize,nRpriority,j, nInput;
        key_t   nKey;
        char    *ptrshm, *ptrs;
        int     nSize;
        struct  strProcess pArray[10];//array of 10 structure
        struct  strProcess *Array;
        //Array = pArray;
        nKey = 5678;
        FILE *f = fopen("logfile.txt", "w");
        if(f == NULL) {
                printf("Error opening file!\n");
                exit(1);
        }
        nSize = sizeof(pArray);
        //create segment
        if((nShmid = shmget(nKey,nSize, IPC_CREAT | 0666)) < 0) {
                perror("shmget");
                exit(1);
        }
        else {
                perror("shmget");
                fprintf(f, "\n shared memory segment created\n");
        }
        Array  = shmat(nShmid, NULL, 0);
        perror("shmat");
        /** loop to create exaCtly 10 process */
        nInput = 10; /** call finval function **/
        for(i = 0 ; i < nInput; i++) {
                if(fork() == 0) {
                        srand(getpid());
                        Array[i].nPid = getpid();
                        nRpriority = rand()%10 + 1;//putting random no b/w 1 to 10..u can call your function also
                        Array[i].nPriority = nRpriority;
                        fprintf(f, "\nprint job created with Pid [%d] and priority number [%d]\n",
                                        Array[i].nPid, Array[i].nPriority);
                        break;//must to avoid repeating
                }
                else {
                        ;//parent does nothing
                }
        }
        shmdt(Array);
        //fprintf(f,"\n total [%d] processes have been created\n",nInput);
        /* call fsortasc(pArray, nInput); */
        fclose(f);
}

我希望它有所帮助。

【讨论】:

  • 但是我不需要密钥来访问客户端中的共享内存
  • 是的,创建的共享内存将被shmidkey标识,你可以使用ipcs -m命令检查。 Key 不是必需的,因为一旦将数据复制到指针(shmat 地址)中,您就可以使用 pointer 访问客户端中的共享内存。
  • 感谢您的帮助。如果我想将一个字符放入数组前面的共享内存中。我该怎么做呢?
  • 您好,很抱歉一直打扰您,但是在客户端程序中接收阵列时出现问题。我试图把它打印出来,但我得到的只是我想知道你能不能帮忙
  • @iAnwar 抱歉,兄弟不需要。我不知道您如何在客户端程序中接收数组,所以我无法猜测。你能修改你的问题并将代码的特定部分放在你没有正确接收到的地方吗?
猜你喜欢
  • 2014-04-28
  • 2016-02-24
  • 2014-07-11
  • 2010-09-24
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多