0

我有以下main.c:

#include <unistd.h> //has thread calls for fork()
#include <stdio.h>

struct globalInfo{
    int x;
};

int do this()
{
    info.x++;
    printf("%d\n",info.x);
    return 0;
}
int main{
    struct globalInfo info = { .x = 2};
    for(int i = 0 ; i < 5 ; i++)
    {
         if(fork() = 0)
         {
             dothis();
         }
    }
 }

这不是我的确切代码,但我的问题在这里更容易演示。

现在上述函数的输出是:

3
3
3
3
3

我想要的是:

3
4
5
6
7

如何在线程之间共享这个结构?似乎每个线程都只是创建自己的结构副本并操作自己的副本。我试图将指向 info 结构的指针作为参数传递给dothis(),但这也不能解决它。我还尝试将信息初始化放在主目录之外;那也没用..

帮助将不胜感激。

4

3 回答 3

2

fork() 不会创建它创建进程的线程,进程将完全具有不同的地址空间,因此即使是全局数据也不会共享数据。

如果您正在考虑线程,请使用 pthreads 以防您正在寻找需要使用 IPC 机制的进程

于 2013-05-16T09:51:06.073 回答
0

使用 anyIPC共享数据 b/w processes。在threads数据中可以通过以下方法共享:

  • pthread_exit传递给并捕获的线程的返回值pthread_join
  • shared/global resourcesynchronizing方法访问的进程
于 2013-05-16T09:07:42.190 回答
0

正如人们已经注意到的那样,您正在创建进程而不是线程。在流程之间共享数据更加困难。每个进程都有自己的内存地址空间,这意味着它们可以共享相同的代码,但它们的数据是私有的。

如果您想在进程之间共享数据,有几种技术。其中之一是带有内存映射的共享内存

#include <unistd.h> //has thread calls for fork()
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

struct globalInfo{
    int x;
};

char *shm = "/asd8"; // change this before every run to avoid error 22

int dothis()
{
    // sleep(1); // helps to simulate race condition
    int len = sizeof(struct globalInfo);

    int fd = shm_open(shm, O_RDWR, 0);
    void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (addr == MAP_FAILED){
        perror(""); // error handling
    }

    struct globalInfo *info = (struct globalInfo *)addr;
    info->x++;
    printf("%d %d\n", info->x, getpid());

    return 0;
}

int main(){
    struct globalInfo info = { .x = 2};
    int len = sizeof(struct globalInfo);

    int fd = shm_open(shm, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    if (fd == -1)
        perror(""); // error handling

    if(ftruncate(fd, len) == -1){
        printf("%d\n", errno); // osx produces error 22 don't know why
        perror("");
    }
    void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    memcpy(addr, &info, len);

    for(int i = 0 ; i < 5 ; i++)
    {
         if(fork() == 0)
         {
             dothis();
             break;
         }
    }
 }

样本输出

3 30588
4 30589
6 30590
6 30591
7 30592

如果您阅读《Linux 编程接口:Linux 和 UNIX 系统编程手册》中的章节,那也很棒

  • 24 进程创建
  • 49 内存映射
  • 53个POSIX信号量(数据共享后必须解决同步问题)
  • 54 POSIX 共享内存
于 2015-11-19T22:56:00.913 回答