在C中的线程之间共享数据

时间:2013-05-16 09:00:55

标签: c multithreading share

我有以下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(),但这也没有解决它。我也尝试将信息初始化放在主要部分之外;这也不起作用..

非常感谢帮助。

3 个答案:

答案 0 :(得分:2)

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

如果您正在考虑线程使用pthreads 如果您正在寻找使用IPC机制所需的流程

答案 1 :(得分:0)

使用任何IPC分享数据b / w processes。在threads中,数据可以通过以下方法共享:

  • 传递给pthread_exit的线程的返回值并捕获pthread_join
  • shared/global resource种方法访问的
  • synchronizing进程

答案 2 :(得分: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

如果您阅读The Linux Programming Interface: A Linux and UNIX System Programming Handbook

中的章节,那也很棒
  • 24流程创建
  • 49内存映射
  • 53 POSIX信号量(共享数据后必须解决同步问题)
  • 54 POSIX共享内存