Windows安装SharedArray

本文提供了一个名为SharedArray的开源项目,用于在Windows和Linux上实现跨进程的内存共享。代码主要用C++编写,通过Python接口进行操作。库支持创建、附加到、删除共享内存,并提供了互斥锁功能确保数据访问的安全性。项目利用numpy数组结构,方便数据转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.https://github.com/imaginary-friend94/Shared-Array-for-Windows

2.修改setup.py

from setuptools import setup, find_packages, Extension
import numpy as np
import sys

if sys.platform == "linux" or sys.platform == "linux2":
    libraries_ext = ["rt"]
elif sys.platform == "win32":
    libraries_ext = []


ext_modules = [
    Extension('SharedArray',
    #extra_compile_args=["-std=c++11"],  #这里更改了c++ 11,我这里使用这种方法会报错,故而取消这个
    sources = ['shared_memory_python.cpp'],
    libraries = libraries_ext,
    language="c++")    #增加了编译语言
]

setup(
        name = 'SharedArray',
        version = '1.2',
        include_dirs = [np.get_include()], #Add Include path of numpy
        ext_modules = ext_modules
      )

3修改 shared_memory_python.cpp

#if defined(_WIN64) || defined(_WIN32) || defined(__CYGWIN__)
#define WIN
#include <Windows.h>
#include <winbase.h>
#include <sddl.h>
#pragma comment(lib, "advapi32.lib")
#elif defined(__linux__)
#define LINUX
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>

struct sem_wrapper
{
    sem_t * sem;
    bool is_locked;
};

#endif

#include "Python.h"
#include "numpy/arrayobject.h"
#include <iostream>
#include <cstdio>
#include <cstring>

#define WIN_SMEM "WINDOWS SHARED MEMORY"
#define ARRAY_STRUCT_SIZE sizeof(PyArrayObject)
#define ARRAY_FULL_SIZE(arr) (size_data_array(arr) + sizeof(int) + arr->nd * sizeof(npy_intp) * 3 + sizeof(int))


#if defined(WIN)

BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
     TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(D;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(D;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators

    if (NULL == pSA)
        return FALSE;

     return ConvertStringSecurityDescriptorToSecurityDescriptor(
                szSD,
                SDDL_REVISION_1,
                &(pSA->lpSecurityDescriptor),
                NULL);
}
#endif

/*
 * copy_from_pointer_array
 * the method returns the number of bytes copied
 */
template <typename ObjectType>
std::size_t copy_from_pointer_array(ObjectType * buffer_dist, ObjectType * buffer_src, size_t len) {
    for (int i = 0; i < len; i++) {
        *buffer_dist = *buffer_src;
        buffer_dist++;
        buffer_src++;
    }
    return len * sizeof(ObjectType);
}

std::size_t size_data_array(PyArrayObject *arr) {
    if (arr->nd == 0)
        return 0;

    std::size_t size = 1;
    for (int i = 0; i < arr->nd; ++i) {
        size *= (int) PyArray_DIM(arr, i);
    }
    size *= PyArray_ITEMSIZE(arr);
    return size;
}

void copy_from_numpy_array_to_buffer(PyArrayObject * array, char * buffer) {
    char * current_pointer = buffer;
    *((int *) current_pointer) = array->nd;
    current_pointer += sizeof(int);
    // dimensions copy
    current_pointer += copy_from_pointer_array(
        (npy_intp * ) current_pointer, 
        (npy_intp * ) array->dimensions, 
        array->nd
    );
    // strides copy
    current_pointer += copy_from_pointer_array(
        (npy_intp * ) current_pointer, 
        (npy_intp * ) array->strides, 
        array->nd
    );
    *((int *) current_pointer) = array->descr->type_num; 
    current_pointer += sizeof(int);

    size_t size_data = size_data_array(array);
    /* Copy data from heap to mmap memory */
    std::memcpy((char *) (current_pointer), (char *) array->data, size_data);
}

PyArrayObject * copy_from_buffer_to_numpy_array(char * buffer) {
    char * current_pointer = buffer;
    int nd = *((int *) current_pointer);
    current_pointer += sizeof(int);
    npy_intp * dims = new npy_intp[nd];

    current_pointer += copy_from_pointer_array(
        (npy_intp * ) dims, 
        (npy_intp * ) current_pointer, 
        nd
    );
    npy_intp * strides = new npy_intp[nd];
    current_pointer += copy_from_pointer_array(
        (npy_intp * ) strides, 
        (npy_intp * ) current_pointer, 
        nd
    );
    int type_num = *((int *) current_pointer);
    current_pointer += sizeof(int);

    PyArrayObject * array = (PyArrayObject *) PyArray_SimpleNewFromData(nd, 
        dims, 
        type_num, 
        (void *) current_pointer
    );
    return array;
}


/*
 * Create a buffer in shared memory
 */
char * create_shared_memory(char * string_shm, int max_buffer_size) {
    bool error_open_file_flag = false;
#if defined(WIN)
    SECURITY_ATTRIBUTES sa;
    if (!CreateMyDACL(&sa))
    {
         // Error encountered; generate message and exit.
        PyErr_SetString(PyExc_RuntimeError, "create_mutex: failed CreateMyDACL");
        return nullptr;
    }
    HANDLE hMapFile;
    hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,
        &sa,
        PAGE_READWRITE,
        0,
        max_buffer_size,
        string_shm);
    if (hMapFile == NULL) error_open_file_flag = true;
#elif defined(LINUX)
    int hMapFile = shm_open(string_shm, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    if (hMapFile < 0){ 
        error_open_file_flag = true; 
    } else {
        if (ftruncate(hMapFile, max_buffer_size) == -1) error_open_file_flag = true;
    }
#endif

    if (error_open_file_flag) {
        PyErr_SetString(PyExc_RuntimeError, "create file is failed");
        return nullptr;
    }

#if defined(WIN)
    char * pBuf = (char *) MapViewOfFile(hMapFile,
                        FILE_MAP_ALL_ACCESS,
                        0,
                        0,
                        max_buffer_size);
#elif defined(LINUX)
    char * pBuf = (char *) mmap(NULL, max_buffer_size, PROT_WRITE | PROT_READ, MAP_SHARED, hMapFile, 0);
#endif

    if (pBuf == nullptr) {
        PyErr_SetString(PyExc_RuntimeError, "memory not allocated");
        return nullptr;
    }

    return pBuf;
}
/*
 * Del a buffer in shared memory
 */
bool delete_shared_memory(char * string_shm) {
#if defined(WIN)
    return true;
#elif defined(LINUX)
    if (shm_unlink(string_shm) == 0) return true;
#endif
}

/*
 * Attach a buffer in shared memory
 */
char * attach_shared_memory(char * string_shm) {
    bool error_open_file_flag = false;
#if defined(WIN)
    HANDLE hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,
        FALSE,
        string_shm); 
    if (hMapFile == NULL) error_open_file_flag = true;
#elif defined(LINUX)
    int hMapFile = shm_open(string_shm, O_RDWR, 0);
    if (hMapFile == -1) error_open_file_flag = true;
#endif

    if (error_open_file_flag) {
        PyErr_SetString(PyExc_RuntimeError, "memory not attached");
        return nullptr;
    }

#if defined(WIN)
    char * pBuf = (char *) MapViewOfFile(hMapFile,
                        FILE_MAP_ALL_ACCESS,
                        0,
                        0,
                        sizeof(size_t));
#elif defined(LINUX)
    char * pBuf = (char *) mmap(0, sizeof(size_t), PROT_WRITE | PROT_READ, MAP_SHARED, hMapFile, 0);
#endif

    size_t full_array_size = *((size_t *) pBuf);

#if defined(WIN)
    UnmapViewOfFile((LPCVOID) pBuf);
    pBuf = (char *) MapViewOfFile(hMapFile,
                        FILE_MAP_ALL_ACCESS,
                        0,
                        0,
                        full_array_size);
#elif defined(LINUX)
    munmap(pBuf, sizeof(size_t));
    pBuf = (char *) mmap(0, full_array_size, PROT_WRITE | PROT_READ, MAP_SHARED, hMapFile, 0);
#endif

    pBuf += sizeof(size_t);

    if (pBuf == nullptr) {
        PyErr_SetString(PyExc_RuntimeError, "memory not attached");
        return nullptr;
    }

    return pBuf;
}

static PyObject *
check_mem_sh(PyObject *self, PyObject *args) 
{
    char * string_shm;
    if (!PyArg_ParseTuple(args, "s", &string_shm)) {
        PyErr_SetString(PyExc_RuntimeError, "set_mem_sh: parse except");
    }
    bool error_open_file_flag = false;

#if defined(WIN)
    HANDLE hMapFile = OpenFileMapping(
        FILE_MAP_ALL_ACCESS,
        FALSE,
        string_shm);
    if (hMapFile == NULL) error_open_file_flag = true;
#elif defined(LINUX)
    int hMapFile = shm_open(string_shm, O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO);
    if (hMapFile == -1) error_open_file_flag = true;
#endif    
    if (error_open_file_flag) {
        Py_INCREF(Py_False);
        return Py_False;
    }
    Py_INCREF(Py_True);
    return Py_True;

}

static PyObject *
create_mem_sh(PyObject *self, PyObject *args)
{
    PyObject * pyobj_for_shrdmem = nullptr;
    char * string_shm;
    if (!PyArg_ParseTuple(args, "sO", &string_shm, &pyobj_for_shrdmem)) {
        PyErr_SetString(PyExc_RuntimeError, "set_mem_sh: parse except");
    }
    PyArrayObject * array_for_shrdmem = (PyArrayObject *) pyobj_for_shrdmem;
    array_for_shrdmem = PyArray_GETCONTIGUOUS(array_for_shrdmem);
    if (array_for_shrdmem->base != nullptr) {
        PyErr_SetString(PyExc_RuntimeError, "set_mem_sh: array is not homogeneous");
    }
    /* Аrray size calculation */ 
    char * shBuf = create_shared_memory(string_shm, ARRAY_FULL_SIZE(array_for_shrdmem));
    if (shBuf == nullptr) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    /* Copy array struct from heap to shared memory */
    *((size_t *) shBuf) = ARRAY_FULL_SIZE(array_for_shrdmem);
    shBuf += sizeof(size_t);
    copy_from_numpy_array_to_buffer(array_for_shrdmem, shBuf);
    Py_INCREF(Py_True);
    return Py_True;
}

static PyObject *
attach_mem_sh(PyObject *self, PyObject *args)
{
    char * string_shm;
    if (!PyArg_ParseTuple(args, "s", &string_shm)) {
        PyErr_SetString(PyExc_RuntimeError, "get_mem_sh: parse except");
    }
    char * shBuf = attach_shared_memory(string_shm);
    if (shBuf == nullptr) {
        Py_INCREF(Py_None);
        return Py_None;
    }

    PyArrayObject * array_for_shrdmem = (PyArrayObject *) shBuf;
    array_for_shrdmem = copy_from_buffer_to_numpy_array(shBuf);
    Py_INCREF((PyObject *) array_for_shrdmem);
    return (PyObject *) array_for_shrdmem;
}

static PyObject *
delete_mem_sh(PyObject *self, PyObject *args) {
    char * string_shm;
    if (!PyArg_ParseTuple(args, "s", &string_shm)) {
        PyErr_SetString(PyExc_RuntimeError, "get_mem_sh: parse except");
    }
    if (delete_shared_memory(string_shm)) {
        Py_INCREF(Py_True);
        return Py_True;
    }
    Py_INCREF(Py_False);
    return Py_False;
}

void mutex_destructor(PyObject * m_obj) {
#if defined(WIN)
    const char * name = PyCapsule_GetName(m_obj);
    HANDLE mut = (HANDLE) PyCapsule_GetPointer(m_obj, PyCapsule_GetName(m_obj));
    delete name;
#elif defined(LINUX)
    const char * name = PyCapsule_GetName(m_obj);
    sem_wrapper * mut = (sem_wrapper *) PyCapsule_GetPointer(m_obj, name);
    if (name != NULL) {
        if (mut->is_locked) {
            sem_post(mut->sem);
            mut->is_locked = false;
        }
        if (name != NULL) {
            delete name;
        }
        delete mut;
    }
#endif
}

static PyObject *
create_mutex(PyObject *self, PyObject *args) {
    bool error_open_file_flag = false;
    char * string_smp;
    if (!PyArg_ParseTuple(args, "s", &string_smp)) {
        PyErr_SetString(PyExc_RuntimeError, "create_mutex: parse except");
        return nullptr;
    }
    char * string_shm_new = new char[strlen(string_smp) + 1];
    strcpy(string_shm_new, string_smp);
#if defined(WIN)
    SECURITY_ATTRIBUTES sa;
    if (!CreateMyDACL(&sa))
    {
         // Error encountered; generate message and exit.
        PyErr_SetString(PyExc_RuntimeError, "create_mutex: failed CreateMyDACL");
        return nullptr;
    }
    HANDLE mut = CreateMutex(
        &sa, 
        FALSE, 
        string_shm_new
    );
    if (mut == nullptr) {
        error_open_file_flag = true;
    }
#elif defined(LINUX)
    sem_wrapper * mut = new sem_wrapper{
        sem_open(string_shm_new, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO, 1), 
        false
    };
    if (mut->sem == SEM_FAILED) {
        error_open_file_flag = true;
    }
#endif
    if (error_open_file_flag) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyCapsule_New((void *) mut, string_shm_new, (PyCapsule_Destructor) mutex_destructor);
}

static PyObject *
open_mutex(PyObject *self, PyObject *args) {
    bool error_open_file_flag = false;
    char * string_smp;
    if (!PyArg_ParseTuple(args, "s", &string_smp)) {
        PyErr_SetString(PyExc_RuntimeError, "open_mutex: parse except");
        return nullptr;
    }
    char * string_shm_new = new char[strlen(string_smp) + 1];
    strcpy(string_shm_new, string_smp);
#if defined(WIN)
    HANDLE mut = OpenMutex(
        MUTEX_ALL_ACCESS, 
        TRUE, 
        string_shm_new
    );
    if (mut == nullptr) error_open_file_flag = true;
#elif defined(LINUX)
    sem_wrapper * mut = new sem_wrapper{
        sem_open(string_shm_new, 0), 
        false
    };
    if (mut->sem == SEM_FAILED) error_open_file_flag = true;
#endif

    if (error_open_file_flag) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    return PyCapsule_New((void *) mut, string_shm_new, (PyCapsule_Destructor) mutex_destructor);
}

static PyObject *
release_mutex(PyObject *self, PyObject *args) {
    PyObject * caps_mutex;
    if (!PyArg_ParseTuple(args, "O", &caps_mutex)) {
        PyErr_SetString(PyExc_RuntimeError, "release_mutex: parse except");
        return nullptr;
    }
#if defined(WIN)
    HANDLE mut = (HANDLE) PyCapsule_GetPointer(caps_mutex, PyCapsule_GetName(caps_mutex));
    ReleaseMutex(mut);
#elif defined(LINUX)
    sem_wrapper * mut = (sem_wrapper *) PyCapsule_GetPointer(caps_mutex, PyCapsule_GetName(caps_mutex));
    if (mut->is_locked) {
        sem_post(mut->sem);
        mut->is_locked = false;
    }
#endif
    Py_INCREF(Py_True);
    return Py_True;
}

static PyObject *
close_mutex(PyObject *self, PyObject *args) {
    PyObject * caps_mutex;
    if (!PyArg_ParseTuple(args, "O", &caps_mutex)) {
        PyErr_SetString(PyExc_RuntimeError, "close_mutex: parse except");
        return nullptr;
    }
    if (caps_mutex != Py_None) {
        mutex_destructor(caps_mutex);
        Py_INCREF(Py_True);
        return Py_True;
    } else {
        Py_INCREF(Py_False);
        return Py_False;    
    }
}

static PyObject *
remove_mutex(PyObject *self, PyObject *args) {
    PyObject * caps_mutex;
    if (!PyArg_ParseTuple(args, "O", &caps_mutex)) {
        PyErr_SetString(PyExc_RuntimeError, "close_mutex: parse except");
        return nullptr;
    }
#if defined(WIN)
    Py_INCREF(Py_True);
    return Py_True;
#elif defined(LINUX)
    sem_wrapper * mut = (sem_wrapper *) PyCapsule_GetPointer(caps_mutex, PyCapsule_GetName(caps_mutex));
    const char * name = PyCapsule_GetName(caps_mutex);
    if (sem_unlink(name) == -1) {
        Py_INCREF(Py_False);
        return Py_False;
    }
    if (name != NULL) {
        delete name;
    }
    delete mut;
    PyCapsule_SetName(caps_mutex, NULL);
    Py_INCREF(Py_True);
    return Py_True;
#endif    
}

static PyObject * _try_capture_mutex(PyObject * caps_mutex, int msec) {
#if defined(WIN)
    HANDLE mut = (HANDLE) PyCapsule_GetPointer(caps_mutex, PyCapsule_GetName(caps_mutex));
    DWORD out;
    if (msec == -1) {
        out = WaitForSingleObject(mut, INFINITE);
    } else {
        out = WaitForSingleObject(mut, (DWORD) msec);
    }
#elif defined(LINUX)
    sem_wrapper * mut = (sem_wrapper *) PyCapsule_GetPointer(caps_mutex, PyCapsule_GetName(caps_mutex));
    int out;
    if (msec == 0) {
        out = sem_trywait(mut->sem);
    } else if (msec != -1) {
        timespec ts;
        ts.tv_nsec = msec * 1000;
        out = sem_timedwait(mut->sem, &ts);
    } else {
        out = sem_wait(mut->sem);
    }
    if (out == 0) mut->is_locked = true;
#endif

    if (out == 0) {
        Py_INCREF(Py_True);
        return Py_True;
    }
    Py_INCREF(Py_False);
    return Py_False;
}

static PyObject *
try_capture_mutex(PyObject *self, PyObject *args) {
    PyObject * caps_mutex;
    int timeout;
    if (!PyArg_ParseTuple(args, "Oi", &caps_mutex, &timeout)) {
        PyErr_SetString(PyExc_RuntimeError, "try_capture_mutex: parse except");
        return nullptr;
    }
    return _try_capture_mutex(caps_mutex, timeout);
}

static PyObject *
capture_mutex(PyObject *self, PyObject *args) {
    PyObject * caps_mutex;
    if (!PyArg_ParseTuple(args, "O", &caps_mutex)) {
        PyErr_SetString(PyExc_RuntimeError, "capture_mutex: parse except");
        return nullptr;
    }
    return _try_capture_mutex(caps_mutex, -1);
}

static PyObject *
get_last_error(PyObject *self, PyObject *args) {
#if defined(WIN)
    PyObject * py_err = Py_BuildValue("i", (unsigned int) GetLastError());
#elif defined(LINUX)
    PyObject * py_err = Py_BuildValue("i", (unsigned int) errno);
#endif
    Py_INCREF(py_err);
    return py_err;
}

// static PyObject *
// test_function(PyObject *self, PyObject *args) {
//     int fd = shm_open("/test_sh_m", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
//     return Py_None;
// }

static PyMethodDef SharedArrayMethods[] = {

    {"create_mem_sh",  create_mem_sh, METH_VARARGS,
     "method for create shared memory named."},
    {"attach_mem_sh",  attach_mem_sh, METH_VARARGS,
     "method for get shared memory named."},
    {"delete_mem_sh",  delete_mem_sh, METH_VARARGS,
     "method for del shared memory named."},
    {"check_mem_sh",  check_mem_sh, METH_VARARGS,
     "method for check shared memory named."},
    {"create_mutex",  create_mutex, METH_VARARGS,
     ""},
    {"open_mutex",  open_mutex, METH_VARARGS,
     ""},
    {"release_mutex",  release_mutex, METH_VARARGS,
     ""},
    {"close_mutex",  close_mutex, METH_VARARGS,
     ""},
    {"try_capture_mutex",  try_capture_mutex, METH_VARARGS,
      ""},
    {"close_mutex",  close_mutex, METH_VARARGS,
     ""},
    {"remove_mutex",  remove_mutex, METH_VARARGS,
     ""},

    {"capture_mutex",  capture_mutex, METH_VARARGS,
     "capture mutex"},
    {"get_last_error",  get_last_error, METH_VARARGS,
     "returns the result of the call GetLastError() function"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef wsamodule = {
    PyModuleDef_HEAD_INIT,
    "SharedArray", 
    NULL, 
    -1,    
    SharedArrayMethods
};

PyMODINIT_FUNC
PyInit_SharedArray(void)
{
    import_array();
    return PyModule_Create(&wsamodule);
}

4.python setup.py develop 

<think>好的,我需要回答用户关于“haredarray”和“SharedArray”在编程或特定语言实现中的区别或用法的问题。首先,我需要确认这两个术语的正确性,可能用户有拼写错误。注意到“haredarray”可能是一个笔误,正确的可能是“SharedArray”,或者在某些语言中有不同的拼写。接下来,我需要查找这两个术语在不同编程语言中的具体用法。 首先,检查常见编程语言中的相关实现。例如,在JavaScript中,有SharedArrayBuffer用于多线程间共享内存,而Julia语言中有一个SharedArray类型,用于在多个进程间共享数据。但用户提到的“haredarray”可能不存在,可能是拼写错误,应该确认是否存在这样的术语。 接着,查看用户提供的引用内容。引用[1]提到Go语言的并发模型,但未直接涉及SharedArray。引用[2]提到Mojo语言,可能与并行计算相关。因此,可能用户的问题涉及到不同语言中的共享数组结构。 接下来,我需要区分不同语言中的实现。例如,在Julia中,SharedArray允许多个进程访问同一块内存区域,而JavaScript的SharedArrayBuffer用于Web Workers之间的共享内存。此外,可能还有其他语言或框架中有类似的结构,但名称可能不同。 需要指出用户可能的拼写错误,并解释正确的术语。例如,指出“haredarray”可能是“SharedArray”的笔误,并分别在不同语言中解释其用法。同时,需要比较不同语言中的实现差异,比如同步机制、内存管理、并发控制等。 最后,生成相关问题,帮助用户进一步理解相关概念,例如不同语言中的共享内存机制、线程与进程的区别、数据竞争的处理方法等。</think>在编程中,`SharedArray`通常指代多线程/多进程环境中共享内存的数据结构,而`haredarray`可能是拼写错误(推测应为`SharedArray`)。以下是不同语言中的具体实现分析: --- ### 一、JavaScript 的 SharedArrayBuffer **用途**:用于在Web Worker线程间共享二进制数据缓冲区 **特性**: 1. 通过`postMessage`传递引用,不同线程直接操作同一块内存 2. 需配合`Atomics`对象实现原子操作避免数据竞争 ```javascript // 主线程 const buffer = new SharedArrayBuffer(16); const arr = new Int32Array(buffer); // 传递给Worker线程后可直接修改 ``` --- ### 二、Julia 的 SharedArray **用途**:多进程(非线程)间共享数据的数组结构 **特性**: 1. 基于分布式内存模型,通过`@everywhere`声明全局变量 2. 进程间自动同步数据变化,但需注意并行写冲突 ```julia using Distributed @everywhere using SharedArrays S = SharedArray{Int}((1000,)) # 创建共享数组 @distributed for i in 1:1000 S[i] = i^2 # 多进程并行写入 end ``` --- ### 三、Go 语言的共享内存机制 虽然Go没有直接名为`SharedArray`的结构,但可通过以下方式实现类似功能: 1. **通道传递指针**:通过`chan`发送数组指针给多个goroutine 2. **互斥锁保护**:使用`sync.Mutex`保证数据访问安全 ```go var sharedArray [10]int var mutex sync.Mutex func worker() { mutex.Lock() sharedArray[0]++ // 临界区操作 mutex.Unlock() } ``` --- ### 四、关键差异对比 | 特性 | JavaScript SharedArrayBuffer | Julia SharedArray | Go 共享内存 | |-------------------|------------------------------|-------------------|-------------------| | 并发模型 | 多线程 | 多进程 | Goroutine协程 | | 同步机制 | Atomics API | 隐式同步 | 互斥锁/通道 | | 内存分配位置 | 主线程堆内存 | 共享内存区域 | 堆内存 | | 典型应用场景 | 浏览器端高性能计算 | 科学计算 | 后端服务并发处理 | --- ### 五、注意事项 1. **数据竞争**:所有共享内存操作需显式同步(如JavaScript的Atomics.wait/notify) 2. **性能权衡**:共享内存减少复制开销,但增加锁竞争风险(如Go中过度使用mutex会导致吞吐量下降) 3. **语言特性适配**:Julia的`SharedArray`适合数值计算并行化,而Go的通道机制更适合事件驱动模型[^1] ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

,,,637

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值