首页 \ 问答 \ 子进程执行的顺序及其对操作原子性的影响(order of subprocesses execution and it's impact on operations atomicity)

子进程执行的顺序及其对操作原子性的影响(order of subprocesses execution and it's impact on operations atomicity)

我正在学习python多处理模块,我发现了这个例子(这是一个有点修改的版本):

#!/bin/env python
import multiprocessing as mp
import random
import string
import time

# Define an output queue
output = mp.Queue()

# define a example function
def rand_string(length, output):
    time.sleep(1)
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(random.choice(
                    string.ascii_lowercase
                    + string.ascii_uppercase
                    + string.digits)
               for i in range(length))
    result = (len(rand_str), rand_str)
    print result
    time.sleep(1)
    output.put(result)


def queue_size(queue):
    size = int(queue.qsize())
    print size


# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(x, output)) for x in range(1,10)]


# Run processes
for p in processes:
    p.start()


# Exit the completed processes
for p in processes:
    p.join()


# Get process results from the output queue
results = [output.get() for p in processes]
print(results)

这个输出如下:

(3, 'amF')
(1, 'c')
(6, '714CUg')
(4, '10Qg')
(5, 'Yns6h')
(7, 'wsSXj3Z')
(9, 'KRcDTtVZA')
(2, 'Qy')
(8, '50LpMzG9')
[(3, 'amF'), (1, 'c'), (6, '714CUg'), (4, '10Qg'), (5, 'Yns6h'), (9, 'KRcDTtVZA'), (2, 'Qy'), (7, 'wsSXj3Z'), (8, '50LpMzG9')]

据我所知,进程不会按照它们的创建顺序调用(使用processes = [mp.Process(target=rand_string, args=(x, output)) for x in range(1,10)] )这在引用中提到文章。 我不明白(或者我不确定是否理解正确)是为什么result的顺序与打印输出result到STDOUT的顺序不一致? 我对此的理解是这三个操作不是原子的(我的意思是它们可以通过进程切换分开):

    print result
    time.sleep(1)
    output.put(result)

基本上,这里发生的是,当进程将results print到STDOUT时,它将切换到另一个写入results进程。 像这样的东西:

Time 
------------------------------------------------------------------------------------------------------------------>
Process1: print results |               |                                    | time.sleep(1) | output.put(result) |
Process2:               | print results | time.sleep(1) | output.put(result) |               |                    |

在这种情况下,STDOUT上的输出将是:

(1, 'c')
(2, 's5')

results的实际内容将是:

[ (2, 's5') (1, 'c')]

出于同样的原因,这些过程并没有按照它们的创建顺序进行。

我对吗?


I'm learning python multiprocessing module and I've found this example (this is a bit modified version):

#!/bin/env python
import multiprocessing as mp
import random
import string
import time

# Define an output queue
output = mp.Queue()

# define a example function
def rand_string(length, output):
    time.sleep(1)
    """ Generates a random string of numbers, lower- and uppercase chars. """
    rand_str = ''.join(random.choice(
                    string.ascii_lowercase
                    + string.ascii_uppercase
                    + string.digits)
               for i in range(length))
    result = (len(rand_str), rand_str)
    print result
    time.sleep(1)
    output.put(result)


def queue_size(queue):
    size = int(queue.qsize())
    print size


# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(x, output)) for x in range(1,10)]


# Run processes
for p in processes:
    p.start()


# Exit the completed processes
for p in processes:
    p.join()


# Get process results from the output queue
results = [output.get() for p in processes]
print(results)

The output of this is following:

(3, 'amF')
(1, 'c')
(6, '714CUg')
(4, '10Qg')
(5, 'Yns6h')
(7, 'wsSXj3Z')
(9, 'KRcDTtVZA')
(2, 'Qy')
(8, '50LpMzG9')
[(3, 'amF'), (1, 'c'), (6, '714CUg'), (4, '10Qg'), (5, 'Yns6h'), (9, 'KRcDTtVZA'), (2, 'Qy'), (7, 'wsSXj3Z'), (8, '50LpMzG9')]

I understand that processes are not called in order which they was created (using processes = [mp.Process(target=rand_string, args=(x, output)) for x in range(1,10)]) this is mentioned in referred article. What I do not understand (or I'm not sure if understand correct) is why the order of result does not corresponds with the order in which print outputs the result to STDOUT? My understanding of this is that those three operations are not atomic (I mean that they can be separated by process switch):

    print result
    time.sleep(1)
    output.put(result)

Basically what happens here is that in the moment when process print the results to STDOUT it is switched to another process which writes to results. Something like that:

Time 
------------------------------------------------------------------------------------------------------------------>
Process1: print results |               |                                    | time.sleep(1) | output.put(result) |
Process2:               | print results | time.sleep(1) | output.put(result) |               |                    |

In this case the output on STDOUT would be:

(1, 'c')
(2, 's5')

But the actual content of results will be:

[ (2, 's5') (1, 'c')]

And for the same reason the processes are not stared in order as they ware created.

Am I right?


原文:https://stackoverflow.com/questions/32192938
更新时间:2024-04-08 10:04

最满意答案

propOrder基于字段/属性名称而不是XML元素名称。 所以你应该有

@XmlType(propOrder = {"name", "active","attributes"})

了解更多信息


The propOrder is based on the field/property name and not the XML element name. So you should have

@XmlType(propOrder = {"name", "active","attributes"})

For More Information

相关问答

更多