当前位置: 首页 > 知识库问答 >
问题:

子进程不能访问C中的共享内存

邵正雅
2023-03-14
struct OverSharedData{
    struct SharedData ** rep;
    int rop;
};

void initialize( struct OverSharedData * bill){
bill->rep = (struct SharedData**)malloc(sizeof(struct SharedData*)*consumerthreads);
int on =0;
for (on=0; on<consumerthreads; on++) {
    *(bill->rep+on) = (struct SharedData *)malloc(sizeof(struct SharedData));
    init(*(bill->rep + on), on); //
 }}

int main(int argc, const char * argv[])
{

    databases(argv[1]); /* Takes care of setting up the database*/
    categories(argv[2]); /*Takes care of setting up the book categories*/
    bookorders = argv[3];

    key_t key = ftok("garbage.txt", 71);
    int eyedee = shmget(key, sizeof(struct OverSharedData ),
                        IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (eyedee == -1)
    {
        perror("shmget");
        exit(1);
    }

    struct OverSharedData *remp = (struct OverSharedData *) shmat(eyedee, 0, 0);

    if (remp == (void *) -1)
    {
        perror("shmat");
        exit(1);
    }

    initialize(remp);
    struct SharedData * d = *(remp->rep + 0);


    printf("Hallo\n");
    shmctl(eyedee, IPC_RMID, 0);



    pid_t forkk = fork();

    if (forkk==0) {
        /*THIS DOES NOT WORK*/
        printf("Entered consumer check: %d\n", remp->rop);

         int z = 0;
         pthread_t Consumer_Threads[consumerthreads];
         for (z=0; z<consumerthreads; z++) {
         remp->rop = z;
         d = *(remp->rep + z);
         d->da = z;
         pthread_create((Consumer_Threads+z), 0, Consumer, d);


         }
         for (z = 0; z<consumerthreads; z++) {
         pthread_join(Consumer_Threads[z], NULL);
         }
         shmdt(remp);

    }

    else{
       /*THIS WORKS*/
        printf("Entered Producer: %d\n",remp->rop);

        pthread_t Produc;
        pthread_create(&Produc, 0, Producer, remp); 
        pthread_join(Produc, NULL);


        printf("Hey guys: %d\n", remp->rop);
        shmdt(remp);
    }

我的猜测是我没有正确地初始化结构,但我不太清楚我做错了什么。我省略了其他一些初始化代码,但我认为,由于我甚至不能访问OverSharedData结构中的int,所以首先不能访问结构更重要。

共有1个答案

东门子昂
2023-03-14

问题是共享数据(单个oversharedData对象)包含指向非共享数据的指针。您需要在共享内存段中分配所有希望共享的数据,而不是使用malloc。类似于:

static void *shared_available;
static size_t shared_left;
void init_shared(size_t size) {
    key_t key = ftok("garbage.txt", 71);
    int eyedee = shmget(key, size,
                        IPC_CREAT | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
    if (eyedee == -1) {
        perror("shmget");
        exit(1); }
    shared_available = shmat(eyedee, 0, 0);
    if (shared_available == (void *) -1) {
        perror("shmat");
        exit(1); }
    shared_left = size;
}
void *alloc_shared(size_t size) {
    void *rv = shared_available;
    if (size > shared_left) {
        fprintf(stderr, "Ran out of shared memory!\n");
        exit(1); }
    shared_available = (char *)rv + size;
    shared_left -= size;
    return rv;
}

OverSharedData *initialize() {
    init_shared(sizeof(struct OverSharedData) +
                       sizeof(struct SharedData *) * consumerthreads +
                       sizeof(struct SharedData) * consumerthreads)
    OverSharedData *bill = alloc_shared(sizeof(OverSharedData));
    bill->rep = alloc_shared(sizeof(struct SharedData*)*consumerthreads);
    for (int on=0; on<consumerthreads; on++) {
        bill->rep[on] = alloc_shared(sizeof(struct SharedData));
        init(&bill->rep[on], on); }
}

如果init例程试图将指向非共享内存的指针存储到shareddata结构中(您没有显示两者的定义,所以我们不能说),上述方法仍然会有问题。

如果您希望能够更灵活地跨进程分配和管理共享内存,您确实需要使用通用共享内存分配器/管理器,例如

 类似资料:
  • 问题内容: 假设我有一个与field共享的对象。多个线程将共享对该对象的引用以访问该字段。但是,线程永远不会同时访问对象。我需要声明为volatile吗? 这样的情况如下: 一个类定义一个唯一字段和一个方法。 一个线程使计数器递增,然后生成另一个使计数器递增的线程,依此类推。 鉴于程序的逻辑,因此无法并发访问计数器。但是,计数器是在多个线程之间共享的。计数器必须波动吗? 的情况的另一个变体是当多个

  • 首先,因为我在一个共享主机上,我不能将我的公共文件夹的内容直接放入root。我必须将整个项目放入public_html目录,并使用. htaccess指向下面的公共文件夹(这对于单个Laravel项目来说很好): 我现在用主机创建了一个子域,它在我的公共html目录中创建了一个名为store的目录。领域通用域名格式。这将是一个完全不同的Laravel项目。如果我将常规文件夹结构与。htaccess

  • 本文向大家介绍C++进程间共享数据实例,包括了C++进程间共享数据实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C++进程间共享数据的实现方法,分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的C++程序设计有所帮助。

  • 问题内容: 我正在尝试编写一个Java应用程序,该应用程序将访问其他 共享 邮箱以阅读电子邮件并执行其他活动。我阅读自己的INBOX(或其文件夹和内容)没有问题,但是很难找到有关如何访问(并最终解析/读取)共享邮箱的信息。 问题答案: 在其他答案的帮助下,我找到了以下解决方案,该解决方案适用于com.sun.mail:javax.mail:1.6.2 使用javax.mail:mail:1.4.7