关于课后作业添加进程锁

关于课后作业添加进程锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# coding:utf-8
import json
import os
import time
 
from common.utils import check_file, timestamp_to_str, save
from common.error import UserExistsError, RoleError, LevelError, CountError
from common.consts import ROLES, FIRST_LEVELS, SECOND_LEVELS
from multiprocessing import Lock
 
 
class Base(object):
    def __init__(self, user_json, gift_json):
        self.user_json = user_json
        self.gift_json = gift_json
        self.lock = Lock()
 
        self.__check_user_json()
        self.__check_gift_json()
        self.__init_gifts()
 
    # 文件检查
    def __check_user_json(self):
        check_file(self.user_json)
 
    def __check_gift_json(self):
        check_file(self.gift_json)
 
    # 操作user:
    # 读取users
    def __read_users(self, time_to_str=False):
        self.lock.acquire()
        try:
            with open(self.user_json, 'r', encoding='utf-8') as f:
                json_data = json.loads(f.read())
 
            if time_to_str:
                for k, v in json_data.items():
                    v['create_time'= timestamp_to_str(v['create_time'])
                    v['update_time'= timestamp_to_str(v['update_time'])
                    json_data[k] = v
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return json_data
 
    # 增加user
    def __write_user(self**user):
        if 'username' not in user:
            raise ValueError('缺少username')
        if 'role' not in user:
            raise ValueError('缺少role')
 
        user['active'= True
        user['create_time'= time.time()
        user['update_time'= time.time()
        user['gifts'= []
 
        self.lock.acquire()
        try:
            users = self.__read_users()
            if user['username'in users:
                raise UserExistsError('用户 %s 已存在' % user['username'])
 
            users.update(
                {user['username']: user}
            )
            save(self.user_json, users)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
 
    # 修改role
    def __change_role(self, username, role):
        self.lock.acquire()
        try:
            users = self.__read_users()
            user = users.get(username)
 
            if not user:
                return False
 
            if role not in ROLES:
                raise RoleError('role只能是admin或者normal')
 
            user['role'= role
            user['update_time'= time.time()
            users[username] = user
            save(self.user_json, users)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return True
 
    # 修改active
    def __change_active(self, username):
        self.lock.acquire()
        try:
            users = self.__read_users()
            user = users.get(username)
 
            if not user:
                return False
 
            user['active'= not user['active']
            user['update_time'= time.time()
            users[username] = user
            save(self.user_json, users)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return True
 
    # 删除user
    def __delete_user(self, username):
        self.lock.acquire()
        try:
            users = self.__read_users()
            user = users.get(username)
 
            if not user:
                return False
 
            del_user = users.pop(username)
            save(self.user_json, users)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return del_user
 
    # 操作gift
    # 读取gifts
    def __read_gifts(self):
        self.lock.acquire()
        try:
            with open(self.gift_json, 'r', encoding='utf-8') as f:
                json_gifts = json.loads(f.read())
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return json_gifts
 
    # gift结构初始化
    def __init_gifts(self):
        data = {
            'level1': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level2': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level3': {
                'level1': {},
                'level2': {},
                'level3': {}
            },
            'level4': {
                'level1': {},
                'level2': {},
                'level3': {}
            }
        }
        self.lock.acquire()
        try:
            gifts = self.__read_gifts()
            if len(gifts) != 0:
                return
            save(self.gift_json, data)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
 
    # 判断gift等级合理性及获取gifts
    def __check_get_gifts(self, first_level, second_level):
        if first_level not in FIRST_LEVELS:
            raise LevelError('第一层level等级错误,只能是level1~level4')
        if second_level not in SECOND_LEVELS:
            raise LevelError('第二层level等级错误,只能是level1~level3')
        self.lock.acquire()
        try:
            gifts = self.__read_gifts()
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        level_one = gifts[first_level]
        level_two = level_one[second_level]
        return {
            'level_one': level_one,
            'level_two': level_two,
            'gifts': gifts
        }
 
    # 添加gift
    def __write_gift(self, first_level, second_level, gift_name, gift_count):
        assert isinstance(gift_count, int), '礼物数量必须是int'
        data = self.__check_get_gifts(first_level, second_level)
        gifts = data.get('gifts')
        level_one = data.get('level_one')
        level_two = data.get('level_two')
 
        if gift_count <= 0:
            gift_count = 1
 
        if gift_name in level_two:
            level_two[gift_name]['count'= level_two[gift_name]['count'+ gift_count
        else:
            level_two[gift_name] = {
                'name': gift_name,
                'count': gift_count
            }
        level_one[second_level] = level_two
        gifts[first_level] = level_one
        self.lock.acquire()
        try:
            save(self.gift_json, gifts)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
 
    # gift数量修改(根据gift_count数量递减)
    def __update_gift(self, first_level, second_level, gift_name, gift_count=1, is_admin=False):
        assert isinstance(gift_count, int), '礼物数量必须是int'
        data = self.__check_get_gifts(first_level, second_level)
        gifts = data.get('gifts')
        level_one = data.get('level_one')
        level_two = data.get('level_two')
 
        if gift_name not in level_two:
            return False
 
        if is_admin:
            if gift_count <= 0:
                raise CountError('礼物数量错误')
            level_two[gift_name]['count'= gift_count
        else:
            if level_two[gift_name]['count'- gift_count < 0:
                raise CountError('礼物数量错误')
            level_two[gift_name]['count'-= gift_count
 
        level_one[second_level] = level_two
        gifts[first_level] = level_one
        self.lock.acquire()
        try:
            save(self.gift_json, gifts)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return True
 
    # gift的删除
    def __delete_gift(self, first_level, second_level, gift_name):
        data = self.__check_get_gifts(first_level, second_level)
        gifts = data.get('gifts')
        level_one = data.get('level_one')
        level_two = data.get('level_two')
 
        if gift_name not in level_two:
            return False
 
        del_gift = level_two.pop(gift_name)
        level_one[second_level] = level_two
        gifts[first_level] = level_one
        self.lock.acquire()
        try:
            save(self.gift_json, gifts)
        except Exception as e:
            raise e
        finally:
            self.lock.release()
        return del_gift

请老师看一下这样添加进程锁对不对,还有请问对于读取json文件时有必要添加进程锁吗以及加锁时有必要加except代码块吗?还是只用try...finally就可以

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

1回答
好帮手慕小猿 2023-05-22 11:46:56

同学,你好!1、同学的添加的进程锁是没有问题的。

2、读取文件时是有必要添加进程锁的,避免同一时间多人操作文件,争抢写入,有的人可能写入不上。用锁可以保证同一时间只有一个人在操作文件,保证了数据的准确性。

3、用try .....except.....finally避免报错而终止程序运行,建议使用try .....except.....finally

祝学习愉快~

  • 老师,这样加进程锁有些地方是有问题的,会出现死锁的问题,比如__read_users()函数中加了锁,然后__write_user()函数中调用__read_users()之前又加了锁,程序就不能正常运行,我又修改了一下,就只是在__read_users()、__read_gifts()以及utils模块中的save()中添加了进程锁,这样应该才是对的嘛?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    # coding:utf-8
    import json
    import multiprocessing
    import os
    import time
     
    from common import utils, consts
    from common.error import (UserExistsError, RoleError, LevelError, NegativeNumberError,
                              CountError)
     
    """
        一、
        1:确定用户表中每个用户的信息字段
        2:读取user.json文件
        3:写入user.json文件(检测该用户是否存在),存在则不可写入
             
        username:姓名
        role:normal or admin
        active:True or False
        create_time:timestamp
        update_time:timestamp
        gifts:[]
        用户信息完整格式:{username: {username: ***, role: ***, active: ***...}}
         
        二、
        1:role的修改
        2:active的修改
        3:delete_user
         
        三、
        1:gifts 奖品结构的确定
        2:gifts 奖品的读取
        3:gifts 添加
        4:gifts 初始化
         
        四、
        1:gifts 修改(数量递减)
        2:gifts 奖品删除
         
        {
            level1: {
                level1: {
                    gift_name1: {
                        name: xxx,
                        count: xxx
                    },
                    gift_name2: {
                        name: xxx,
                        count: xxx
                    }
                },
                level2: {},
                level3: {}
            },
            level2:{
                level1: {},
                level2: {},
                level3: {}
            },
            level3:{
                level1: {},
                level2: {},
                level3: {}
            },
            level4:{
                level1: {},
                level2: {},
                level3: {}
            }
        }  
           
    """
     
     
    class Base(object):
        def __init__(self, user_json, gift_json):
            self.user_json = user_json
            self.gift_json = gift_json
            self.lock = multiprocessing.Manager().Lock()
     
            self.__check_user_json()
            self.__check_gift_json()
            self.__init_gifts()
     
        def __check_user_json(self):
            utils.check_file(self.user_json)
     
        def __check_gift_json(self):
            utils.check_file(self.gift_json)
     
        def __read_users(self, time_to_str=False):
            try:
                self.lock.acquire()
                with open(self.user_json, 'r', encoding='utf-8') as f:
                    data = json.loads(f.read())
     
                if time_to_str:
                    for k, v in data.items():
                        v['create_time'= utils.timestamp_to_string(v['create_time'])
                        v['update_time'= utils.timestamp_to_string(v['update_time'])
                        data[k] = v
            except Exception as e:
                raise e
            finally:
                self.lock.release()
     
            return data
     
        def __write_user(self**user):
            if 'username' not in user:
                raise ValueError('missing username')
            if 'role' not in user:
                raise ValueError('missing role')
     
            user['active'= True
            user['create_time'= time.time()
            user['update_time'= time.time()
            user['gifts'= []
     
            users = self.__read_users()
     
            if user['username'in users:
                raise UserExistsError('username %s had exists' % user['username'])
     
            users.update(
                {user['username']: user}
            )
            utils.save(users, self.user_json, self.lock)
     
        def __change_role(self, username, role):        
            users = self.__read_users()
            user = users.get(username)  # {'username': {username: ***, role: *** ...}}
     
            if not user:
                return False
     
            if role not in consts.ROLES:
                raise RoleError('not use role %s' % role)
     
            user['role'= role
            user['update_time'= time.time()
            users[username] = user
            utils.save(users, self.user_json, self.lock)    
             
            return True
     
        def __change_active(self, username):        
            users = self.__read_users()
            user = users.get(username)
     
            if not user:
                return False
     
            user['active'= not user['active']
            user['update_time'= time.time()
            users[username] = user
            utils.save(users, self.user_json, self.lock)  
             
            return True
     
        def __delete_user(self, username):
            users = self.__read_users()
            user = users.get(username)
     
            if user is None:
                return False
     
            del_user = users.pop(username)        
            utils.save(users, self.user_json, self.lock)   
             
            return del_user
     
        def __read_gitfs(self):
            try:
                self.lock.acquire()
                with open(self.gift_json, 'r', encoding='utf-8') as f:
                    data = json.loads(f.read())
            except Exception as e:
                raise e
            finally:
                self.lock.release()
     
            return data
     
        def __init_gifts(self):
            data = {
                'level1': {
                    'level1': {},
                    'level2': {},
                    'level3': {}
                },
                'level2': {
                    'level1': {},
                    'level2': {},
                    'level3': {}
                },
                'level3': {
                    'level1': {},
                    'level2': {},
                    'level3': {}
                },
                'level4': {
                    'level1': {},
                    'level2': {},
                    'level3': {}
                }
            }
     
            gifts = self.__read_gitfs()
             
            if len(gifts) != 0:
                return
             
            utils.save(data, self.gift_json, self.lock)        
     
        def __write_gift(self, first_level, second_level, gift_name, gift_count):        
            assert isinstance(gift_count, int), 'gift count is int'
            data = self.__check_get_gift(first_level, second_level)
     
            gifts = data.get('gifts')
            first_pool = data.get('level_one')
            second_pool = data.get('level_two')
     
            if gift_count <= 0:
                gift_count = 1
     
            if gift_name in second_pool:
                second_pool[gift_name]['count'= second_pool[gift_name]['count'+ gift_count
            else:
                second_pool[gift_name] = {
                    'name': gift_name,
                    'count': gift_count
                }
            first_pool[second_level] = second_pool
            gifts[first_level] = first_pool
            utils.save(gifts, self.gift_json, self.lock)        
     
        def __gift_update(self, first_level, second_level, gift_name, gift_count=1,
                          is_admin=False):        
            assert isinstance(gift_count, int), 'gift count is int'
            data = self.__check_get_gift(first_level, second_level)
     
            gifts = data.get('gifts')
            first_pool = data.get('level_one')
            second_pool = data.get('level_two')
     
            if gift_name not in second_pool:
                return False
     
            current_gift = second_pool[gift_name]
     
            if is_admin:
                if gift_count <= 0:
                    raise CountError('gift count must bigger 0')
                current_gift['count'= gift_count
            else:
                if current_gift['count'- gift_count < 0:
                    raise NegativeNumberError('gift_count can\'t negative')
                current_gift['count'-= gift_count
            second_pool[gift_name] = current_gift
            first_pool[second_level] = second_pool
            gifts[first_level] = first_pool
            utils.save(gifts, self.gift_json, self.lock)        
     
        def __delete_gift(self, first_level, second_level, gift_name):        
            data = self.__check_get_gift(first_level, second_level)
            first_pool = data.get('level_one')
            second_pool = data.get('level_two')
            gifts = data.get('gifts')
     
            if gift_name not in second_pool:
                return False
     
            del_data = second_pool.pop(gift_name)
            first_pool[second_level] = second_pool
            gifts[first_level] = first_pool
            utils.save(gifts, self.gift_json, self.lock)
             
            return del_data
     
        def __check_get_gift(self, first_level, second_level):
            if first_level not in consts.FIRST_LEVELS:
                raise LevelError('first_level not exists')
            if second_level not in consts.SECOND_LEVELS:
                raise LevelError('second_level not exists')
     
            gitfs = self.__read_gitfs()
            level_one = gitfs.get(first_level)
            level_two = level_one.get(second_level)
     
            return {
                'level_one': level_one,
                'level_two': level_two,
                'gifts': gitfs
            }
    1
    2
    3
    4
    5
    6
    def save(data, path, lock):
        lock.acquire()
        json_data = json.dumps(data, ensure_ascii=False)
        with open(path, 'w', encoding='utf-8') as f:
            f.write(json_data)
        lock.release()


    2023-05-23 16:28:33
  • 同学,你好!老师理解错了同学的意思,抱歉!老师理解是问写入数据时是否需要加锁。同学问的是读取数据的时候是否需要加锁。读取数据时不需要加锁,因为都是从文件中读取数据,不存在数据修改的问题。数据没有改变谁读取都是一样的数据,所以读取可以不添加锁的。在写入数据时添加锁是必要的。因为同一时间多人改文件,有的人改完文件保存了,可能另一个人以为改的还是原来文件(其实文件已发生变化)可能会造成数据不统一的问题。所以写入的时候是需要加锁的。同学只需在_save方法写入文件时添加锁就可以的。

    https://img1.sycdn.imooc.com//climg/646c863109069c5605780414.jpg

    祝学习愉快~

    2023-05-23 17:25:17
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师
插入代码