我读到线程共享它的父线程的内存地址空间.如果这是真的,为什么线程函数不能访问属于它的父线程的局部变量?
void* PrintVar(void* arg){
printf( "%d\n", a);
}
int main(int argc, char*argv[]) {
int a;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, NULL );
}
Run Code Online (Sandbox Code Playgroud)
如果线程共享地址空间,那么PrintVar函数应该能够打印出来的值variable a吧?
我在http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html上阅读了这条信息.
同一进程中的线程共享:进程指令大多数数据打开文件(描述符)信号和信号处理程序当前工作目录用户和组ID
如果这是真的,那么为什么int a不能作为共享变量?
我想看一个共享文件描述符的示例代码
我想深入研究源代码,以实际研究这些机制是如何实现的.(例如,同步,易变,......等)
但代码库是如此巨大,我不知道从哪里开始.
(http://www.java2s.com/Open-Source/Java-Document/CatalogJava-Document.htm)
谁能给我一些线索?非常感谢!
我有一个系统应用程序,它作为unix上12个进程的集合运行.有一个监视进程,它与其他11个进程交换数据.
IPC的要求是使这11个过程与监控过程进行通信,并以最有效的方式设计.你们可以权衡以下两个选项,或建议一个更好的选项.
1)具有UDP套接字通信,其中这11个进程将定期将数据推送到监视器进程.监控过程只是监听和捕获足够好的信息.
要么
2)具有共享内存实现.所以有11个共享内存段,每个段在2个进程(进程ith和监视进程)之间共享.
对于共享内存,它似乎更快但需要锁定/同步,其中在udp中,内核将数据从一个进程的内存空间复制到另一个进程.
任何人都可以提供更多输入来帮助更好地评估这两种方法.?谢谢.
我想知道您是否可以通过使用内存映射文件对单个文件进行多线程写入,并确保两个线程不会写入同一区域(例如,通过插入固定大小的记录),从而减轻了同步需求在应用程序级别,即在我的代码中不使用关键部分或互斥体。
但是,在谷歌搜索了一段时间之后,我仍然不确定。Microsoft的此链接说:
首先,由于两个进程共享内存的物理页面和用于备份内存映射文件的硬盘存储页面,因此明显节省了资源。其次,只有一组数据,因此所有视图始终是一致的。这意味着,通过一个进程的视图对内存映射文件中的页面所做的更改会自动反映在另一进程的内存映射文件的公共视图中。从本质上讲,Windows NT不需要进行任何特殊的记账来确保两个应用程序的数据完整性。
但这是否适用于属于同一进程的线程?这是合理的(因为我的写作是不相交的),但是我对内存映射的底层实现(例如,操作系统做的记账)了解得还不够。
用例示例,其中myFunction由每个线程执行:
// crt - index of current thread, in 0..n-1
// n - thread count
// memArea - pointer to memory location obtained from mapping a file
void myFunction(int crt, int n, int*memArea){
for (int i=1; i<512; i++)
memArea[ ( sizeof(int)*( n*i + crt ) ] = n*i+crt;
}
Run Code Online (Sandbox Code Playgroud)
如果要运行此命令,请等待线程完成,取消映射文件并退出,我是否最终会得到包含连续整数的文件?
我将不胜感激。
我们有一个庞大的Fortran/MPI代码库,它使用节点上的system-V共享内存段.我们运行在具有32个处理器的胖节点上,但只有2或4个NIC,每个CPU的内存相对较少; 所以我们的想法是建立一个共享内存段,每个CPU在其上执行计算(在其SMP数组块中).然后,MPI用于处理节点间通信,但仅用于SMP组中的主节点.该程序是双缓冲的,并且对我们很有效.
当我们决定切换到异步通信时,出现了一些延迟隐藏的问题.由于节点上只有几个CPU通过MPI进行通信,但所有CPU都看到了接收到的阵列(通过共享内存),CPU不知道通信CPU何时完成,除非我们制定了某种障碍,并且那么为什么要进行异步通信呢?
理想的假设解决方案是将请求标记放在SMP段中,并在需要知道的CPU上运行mpi_request_get_status.当然,请求标记只在通信CPU上注册,所以它不起作用!另一个提议的可能性是在通信线程上分支线程并使用它在循环中运行mpi_request_get_status,并在共享内存段中使用flag参数,因此所有其他映像都可以看到.不幸的是,这也不是一种选择,因为我们不能使用线程库.
我们提出的唯一可行的选择似乎有效,但感觉就像一个肮脏的黑客.我们在接收缓冲区的上限地址中放置了一个不可能的值,这样一旦mpi_irecv完成,该值就会改变,因此每个CPU都知道它何时可以安全地使用缓冲区.这可以吗?如果可以保证MPI实现连续传输数据,它似乎只能可靠地工作.这几乎听起来令人信服,因为我们已经在Fortran中编写了这个东西,因此我们的数组是连续的; 我会想象访问也是如此.
有什么想法吗?
谢谢,乔利
这是我正在做的事情的伪代码模板.没有把代码作为参考在家里,所以我希望我没有忘记任何关键的东西,但我会确保当我回到办公室时......
pseudo(array_arg1(:,:), array_arg2(:,:)...)
integer, parameter : num_buffers=2
Complex64bit, smp : buffer(:,:,num_buffers)
integer : prev_node, next_node
integer : send_tag(num_buffers), recv_tag(num_buffers)
integer : current, next
integer : num_nodes
boolean : do_comms
boolean, smp : safe(num_buffers)
boolean, smp : calc_complete(num_cores_on_node,num_buffers)
allocate_arrays(...)
work_out_neighbours(prev_node,next_node)
am_i_a_slave(do_comms)
setup_ipc(buffer,...)
setup_ipc(safe,...)
setup_ipc(calc_complete,...)
current = 1
next = mod(current,num_buffers)+1
safe=true
calc_complete=false
work_out_num_nodes_in_ring(num_nodes)
do i=1,num_nodes
if(do_comms)
check_all_tags_and_set_safe_flags(send_tag, recv_tag, safe) # just in case anything else has finished.
check_tags_and_wait_if_need_be(current, send_tag, recv_tag)
safe(current)=true
else
wait_until_true(safe(current)) …Run Code Online (Sandbox Code Playgroud) 问题
我正在使用Python的多处理模块来异步执行功能。我想做的是能够跟踪每个进程调用和执行时脚本的总体进度def add_print。例如,我希望下面的代码在每次进程运行该函数时将其加1 total并打印出值(1 2 3 ... 18 19 20)。我的第一次尝试是使用全局变量,但这没有用。由于该函数是异步调用的,因此每个进程读取total为0开始,并独立于其他进程加1。因此,输出为20 1而不是递增值。
即使函数是异步运行的,我如何才能以同步方式从映射函数中引用相同的内存块?我的一个想法是以某种方式缓存total在内存中,然后在添加到时引用该确切的内存块total。这是python中一种可能且基本合理的方法吗?
请让我知道您是否需要更多信息或我的解释不够充分。
谢谢!
码
#!/usr/bin/python
## Import builtins
from multiprocessing import Pool
total = 0
def add_print(num):
global total
total += 1
print total
if __name__ == "__main__":
nums = range(20)
pool = Pool(processes=20)
pool.map(add_print, nums)
Run Code Online (Sandbox Code Playgroud) python asynchronous shared-memory multiprocessing shared-state
我是Boost的新手.我有以下结构,并希望使用Boost将其存储在共享内存中.
struct InData{
int x,y,h,w;
char* lbl;
};
Run Code Online (Sandbox Code Playgroud)
反过来,这个结构将存储在Vector中.大多数示例都讨论了Vectors的int或string数据类型.我想如果有人可以举例说明如何将用户定义的数据类型存储到boost共享内存中.
C++程序进程使用OpenCV捕获图像.另一个使用Python和OpenCV的进程有一个共享内存区域(带有mmap)和第一个程序.
如何在Python进程中创建对共享内存区域中已存在的同一图像的引用?Python过程中的这一部分可以编写为C模块并导入到Python中.
对于我的特定需求,只有C++进程创建和写入数据,而Python进程只是读取(并处理)它.
给定相同的图像,所述data的C字段++ cv::Mat和numpy.array是相等的(相同的大小和内容).所以没有必要转换.
由于语言已经分离了内存管理器,因此可能必须使用一些外部同步(例如,信号量)来避免一个进程使用另一个进程中的释放区域.
我的问题是在Python numpy.array对象中创建数据字段指向共享内存中的特定区域.
我开发了一种使用PHP进行异步任务的方法,它一直运行良好,直到现在.
该逻辑基于3个扩展 PCNTL,POSIX和Semaphore.
要完全控制主进程和子进程,我必须共享任务的状态和它们之间的PID.这两个变量使用shm_attach共享 ,fork使用pcntl_fork.
此问题标题中描述的问题与任务的状态和它们之间的PID有关.使用shm_attach 方法共享这两个变量, 因为没有更多可用空间可共享创建共享内存.
我用了2个时间:在构造函数中创建共享内存
<?php
//...
final public function __construct() {
self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);
$this->var_key_pid = $this->alocatesharedMemory(getmypid(), 112112105100); //112112105100;
$this->var_key_status = $this->alocatesharedMemory('PENDING', 11511697116117115); //11511697116117115;
}
Run Code Online (Sandbox Code Playgroud)
并且在run分叉后的方法上
<?php
final public function run($parameters) {
//...
} else { //Frok process
ignore_user_abort(); //I dont know why but must be set again.
$sid = posix_setsid();
self::$shmId = shm_attach((int) (ftok(self::$file, 'A') …Run Code Online (Sandbox Code Playgroud) 我正在尝试采用我的代码来利用MPI共享内存。
为了使事情尽可能简单,假设我只有两个核心。核心A需要来自核心b的size_b数组,而核心b需要来自核心a的size_a数组
在核心A上执行时,我可以执行以下操作吗?
call MPI_WIN_ALLOCATE_SHARED(size_a_in_BYTES, disp_unit, MPI_INFO_NULL, comm_shm, ptr, win_a, mpierr)
call C_F_pointer(ptr, fptr, (/size_a/))
Run Code Online (Sandbox Code Playgroud)
对于核心B
call MPI_WIN_ALLOCATE_SHARED(size_b_in_BYTES, disp_unit, MPI_INFO_NULL, comm_shm, ptr, win_b, mpierr)
call C_F_pointer(ptr, fptrb, (/size_b/))
Run Code Online (Sandbox Code Playgroud)
现在,假设我事后分别通过MPI_SEND / RECV win_a和win_b与核心B和核心a进行通信。现在的逻辑是按照以下方式进行两个查询
核心A:
call MPI_WIN_SHARED_QUERY( win_b
& , rank_of_core_B
& , size_b
& , disp_unit
& , ptr_buf
& , mpierr )
call C_F_pointer(ptr_buf, fptr_query_A, (/size_b/))
Run Code Online (Sandbox Code Playgroud)
反之亦然,核心B
假设我知道在Core B中将我的指针指向fptrb一个数组,即
fptrb = GIVEN_ARRAY_OF_SIZEB
Run Code Online (Sandbox Code Playgroud)
然后,我能否通过访问fptr_query_A例如在CORE中检索内存
fptr_recv = fptr_query_A
Run Code Online (Sandbox Code Playgroud)
在fptr_recv与相同KIND的内核A中声明的指针在哪里fptr_query_A
我之所以这样问是因为,从手册中还不清楚例程是否MPI_WIN_ALLOCATE_SHARED除了为comm_shm共同使用外,是否还必须对所有共享内存核具有相同的胜利和规模。
请在回答时,我认为我的一些困惑是由于以下原因
1)进行呼叫 …