class EmbeddingWorker(Process): def __init__(self, queue, X, y, transformation_method, embedding_args): super().__init__() self.pause_lock = Semaphore(value=True) # lock is free self.embedding_args = embedding_args self.X = X self.y = y self.transformation_method = transformation_method self.queue = queue def callback(self, command, iteration, payload): # pausing acquires pause_lock and the following code only runs if # pause_lock is free with self.pause_lock: self.queue.put((command, iteration, payload)) def run(self): self.transformation_method(self.X, self.y, self.embedding_args, self.callback) def pause(self): self.pause_lock.acquire() def resume(self): self.pause_lock.release() def is_paused(self): return not self.pause_lock.get_value()
def init_wait(): enter = Value('d', 0) out = Value('d', 0) surgeries_available = Semaphore(5) enter_lock = Lock() out_lock = Lock() print('Consultorios disponibles: ' + str(surgeries_available.get_value())) enter_process = Process(target=going_in, args=(surgeries_available, enter, enter_lock)) out_process = Process(target=going_out, args=(surgeries_available, out, out_lock)) enter_process.start() out_process.start()
class QueueifyPipeConnection: """ 管道Pipe队列化的连接器。 主要是为了实现与队列使用方法一致的接口。 """ __slots__ = '_p1', '_p2', '_empty', '_unfinished_tasks', '_lock' def __init__(self, p1, p2): self._p1 = p1 self._p2 = p2 # 由于是进程间的数据同步,所以这里只能使用通过进程信号量来共享计数数据。 # 在这里的信号量仅仅是用于计数put和get的差量。 self._unfinished_tasks = Semaphore(0) # 空队列事件,这将用于join。 self._empty = ProcessEvent() self._lock = ProcessLock() def put(self, value): with self._lock: # 队列数据计数+1 self._unfinished_tasks.release() self._empty.clear() self._p1.send(value) def get(self): return self._p2.recv() def task_done(self): """ 完成一项任务。""" with self._lock: # 队列数据计数-1 self._unfinished_tasks.acquire(False) # 为了实现方法join,当取出后队列的数据量为0,那么空队列事件置位。 if not self._unfinished_tasks.get_value(): self._empty.set() def join(self): """ 等待队列化管道被取完。""" self._empty.wait() def empty(self): """ 返回队列未完成任务是否为空。""" return self._empty.is_set()
def init_wait(): surgeries_qty = 5 min_arrival = 1 max_arrival = 3 min_departure = 5 max_departure = 7 opts, args = getopt(sys.argv[1:], 'a:b:c:d:e:') for (opt, value) in opts: if opt == '-a': surgeries_qty = int(value) elif opt == '-b': min_arrival = int(value) elif opt == '-c': max_arrival = int(value) elif opt == '-d': min_departure = int(value) elif opt == '-e': max_departure = int(value) enter = Value('d', 0) out = Value('d', 0) surgeries_available = Semaphore(surgeries_qty) enter_lock = Lock() out_lock = Lock() print('Consultorios disponibles: ' + str(surgeries_available.get_value())) enter_process = Process(target=going_in, args=(surgeries_available, enter, enter_lock, min_arrival, max_arrival)) out_process = Process(target=going_out, args=(surgeries_available, out, out_lock, min_departure, max_departure)) enter_process.start() out_process.start()
class MainWindow(QMainWindow): """ Mainwindow class operates the pyqt5 window and all of its widgets. It also hosts most of the basic methods connected to the widgets. There are start and stop methods, and a waiter thread that keeps an eye on the finite measurement. Settings typed by the user get stored in a dictionary class and get updated before each measurement call. Mainwindow launches all of the subprocesses connecting to the daqmx cards. Communication between threads and mainwindow is established via pyqtSignals, between mainwindow and subprocesses via multiprocessing queue. The main control variable for measurements is a multiprocessing event variable. """ def __init__(self): super(MainWindow, self).__init__() """ Init hosts all the variables and UI related functionality. The following classes can not be initializes in here, because they inherit from multiprocessing.Process: libs.Counter, libs.Laser and libs.dataProcesser. Arguments have to be passed by inheritance, later there's no possibility, due to their separation from the main loop. libs.Animation also gets instanciated later, due to the window launching functionality in its init method. """ self._dict = libs.UIsettings.UIsettings() self._files = libs.SaveFiles.SaveFiles() self._changeRA = libs.ChangeReadArray.ChangeReadArray() self._timetrace = libs.Timetraces.Timetrace() self._r = libs.Refresh.Refresh() self._readArraySize = int(1e3) # Queues, Semaphores and Events all derived from the multiprocessing library self._dataQ1 = mpQueue() self._dataQ2 = mpQueue() self._animDataQ1 = mpQueue() self._animDataQ2 = mpQueue() self._running = mpEvent() self._semaphore = Semaphore(3) # pyqtSignals self.signal = Communicate() self.signal.stopMeasurement.connect(self.stopBtn) self.signal.measurementProgress.connect(lambda x: self.setProgressBar(x)) self.signal.warning.connect(self.warnPopUp) self.signal.displayRates.connect(lambda x: self.displayRatesOnLCD(x)) self.signal.convertDone.connect(lambda: self.statusBar.showMessage('Conversion done!')) self.signal.alreadyConverted.connect(lambda: self.statusBar.showMessage('Already converted!')) self.signal.noData.connect(lambda: self.statusBar.showMessage('No data files in this directory!')) # ################## # # Window and widgets # # ################## # self.setGeometry(500, 300, 500, 200) # x, y, width, height self.setWindowTitle('ALEX') # ## Statusbar self.statusBar = QStatusBar() self.setStatusBar(self.statusBar) self.statusBar.showMessage("idle") # ## file menue # load app, loads laser settings from file self.loadApp = QAction('Load settings', self) self.loadApp.setShortcut('Ctrl+l') self.loadApp.triggered.connect(self.loadDict) # save app, saves measurement settings to file self.saveApp = QAction('Save settings', self) self.saveApp.setShortcut('Ctrl+s') self.saveApp.triggered.connect(lambda: self._files.saveSetsDict(self._dict._a, self.getDirectory(), 'Measurement_settings')) # convert data to photon-hdf5 self.convertData = QAction('Convert raw data to photon-hdf5', self) self.convertData.setShortcut('Ctrl+c') self.convertData.triggered.connect(lambda: self._files.convertToPhotonHDF5(self.getDirectory(), self.signal)) # change ReadArray size self.setArraySize = QAction('Read arrays size', self) self.setArraySize.setShortcut('Ctrl+a') self.setArraySize.triggered.connect(self.changeArraySize) # close the app self.closeApp = QAction('Close', self) self.closeApp.setShortcut('Ctrl+q') self.closeApp.triggered.connect(self.closeApplication) self.menueLayout() # ## GroupBox Directory: # Group contains: # - Location display QLineEdit # - Browse directories QPushButton filesGroup = QGroupBox('Directory') hbox12 = QHBoxLayout() filesGroup.setLayout(hbox12) self._location = QLineEdit() self._location.setToolTip("Please select a directory. If you do not, the data will not be saved!") self._location.setMaxLength(100) self._location.setReadOnly(True) hbox12.addWidget(self._location) hbox12.setSpacing(10) self._browseButton = QPushButton('Browse', self) self._browseButton.clicked.connect(self.getFileLocation) hbox12.addWidget(self._browseButton) # ## label for different widgets self.label1 = QLabel("Laserpower green") self.label2 = QLabel("Laserpower red") self.label3 = QLabel("Ratio of illumination\ngreen/red") self.label4 = QLabel("ALEX\nfrequency [Hz]") self.label5 = QLabel("Measurement\nduration [s]") self.label6 = QLabel("Measurement mode") self.label7 = QLabel("Counts in green channel") self.label8 = QLabel("Counts in red channel") self.label9 = QLabel("% Green") self.label10 = QLabel("% Red") # ## GroupBox Laser: # Group contains: # - Laser power red slider # - Laser power red spinbox # - Laser power green slider # - Laser power green spinbox # - Laser period percentage slider # - Laser period percentage red spinbox # - Laser period percentage green spinbox laserGroup = QGroupBox("Laser settings") hbox1 = QHBoxLayout() hbox1.setSpacing(30) hbox2 = QHBoxLayout() hbox2.setSpacing(30) hbox9 = QHBoxLayout() hbox11 = QHBoxLayout() hbox11.setSpacing(30) hbox10 = QHBoxLayout() hbox10.setSpacing(30) vbox1 = QVBoxLayout() vbox1.addWidget(self.label2) vbox1.addLayout(hbox1) vbox1.addStretch(1) vbox1.addWidget(self.label1) vbox1.addLayout(hbox2) vbox1.addStretch(1) vbox1.addWidget(self.label3) vbox1.addLayout(hbox9) vbox1.addStretch(1) vbox1.addLayout(hbox11) vbox1.addStretch(1) vbox1.addLayout(hbox10) vbox1.addStretch(1) laserGroup.setLayout(vbox1) hbox11.addWidget(self.label9) hbox11.addWidget(self.label10) # Laserpower slider red self.sld_red = QSlider(Qt.Horizontal, self) self.sld_red.setFocusPolicy(Qt.NoFocus) self.sld_red.setGeometry(80, 20, 50, 10) self.sld_red.setMinimum(0) self.sld_red.setMaximum(100) self.sld_red.setValue(50) self.sld_red.setTickPosition(QSlider.TicksBelow) self.sld_red.setTickInterval(20) self.sld_red.valueChanged.connect(lambda: self.refreshUI(0, 'sld_red', self.sld_red.value())) hbox1.addWidget(self.sld_red) # Laserpower QSpinBox red self.sb_red = QSpinBox(self) self.sb_red.setMinimum(0) self.sb_red.setMaximum(100) self.sb_red.setValue(50) self.sb_red.valueChanged.connect(lambda: self.refreshUI(1, 'sb_red', self.sb_red.value())) hbox1.addWidget(self.sb_red) # Laserpower slider green self.sld_green = QSlider(Qt.Horizontal, self) self.sld_green.setFocusPolicy(Qt.NoFocus) self.sld_green.setGeometry(160, 40, 100, 30) self.sld_green.setMinimum(0) self.sld_green.setMaximum(100) self.sld_green.setValue(50) self.sld_green.setTickPosition(QSlider.TicksBelow) self.sld_green.setTickInterval(20) self.sld_green.valueChanged.connect(lambda: self.refreshUI(0, 'sld_green', self.sld_green.value())) hbox2.addWidget(self.sld_green) # Laserpower QSpinBox green self.sb_green = QSpinBox(self) self.sb_green.setMinimum(0) self.sb_green.setMaximum(100) self.sb_green.setValue(50) self.sb_green.valueChanged.connect(lambda: self.refreshUI(1, 'sb_green', self.sb_green.value())) hbox2.addWidget(self.sb_green) # Illumination percentage slider self.sld_percentage = QSlider(Qt.Horizontal, self) self.sld_percentage.setFocusPolicy(Qt.NoFocus) self.sld_percentage.setGeometry(160, 40, 100, 30) self.sld_percentage.setMinimum(0) self.sld_percentage.setMaximum(100) self.sld_percentage.setTickPosition(QSlider.TicksBelow) self.sld_percentage.setTickInterval(10) self.sld_percentage.setValue(50) self.sld_percentage.valueChanged.connect(lambda: self.refreshUI(0, 'sld_percentage', self.sld_percentage.value())) hbox9.addWidget(self.sld_percentage) # Illumination percentage QSpinBox green self.sb_percentG = QSpinBox(self) self.sb_percentG.setMinimum(0) self.sb_percentG.setMaximum(100) self.sb_percentG.setValue(50) self.sb_percentG.valueChanged.connect(lambda: self.refreshUI(1, 'sb_percentG', self.sb_percentG.value())) hbox10.addWidget(self.sb_percentG) # Illumination QSpinBox red self.sb_percentR = QSpinBox(self) self.sb_percentR.setMinimum(0) self.sb_percentR.setMaximum(100) self.sb_percentR.setValue(50) self.sb_percentR.valueChanged.connect(lambda: self.refreshUI(1, 'sb_percentR', self.sb_percentR.value())) hbox10.addWidget(self.sb_percentR) # ## APD GroupBox # Group contains: # - Laser alternation frequency spinbox # - Measurement mode continuous radiobutton # - Measurement mode finite radiobutton # - Measurement duration spinbox apdGroup = QGroupBox("Measurement") hbox3 = QHBoxLayout() hbox3.setSpacing(30) hbox4 = QHBoxLayout() hbox4.setSpacing(30) hbox5 = QHBoxLayout() hbox5.setSpacing(30) vbox2 = QVBoxLayout() vbox2.addLayout(hbox3) vbox2.addStretch(1) vbox2.addLayout(hbox4) vbox2.addStretch(1) vbox2.addWidget(self.label6) vbox2.addLayout(hbox5) apdGroup.setLayout(vbox2) hbox3.addWidget(self.label4) hbox3.addWidget(self.label5) # Sample frequence QSpinBox self.sb_sampFreq = QSpinBox(self) self.sb_sampFreq.setMinimum(100) self.sb_sampFreq.setMaximum(100000) self.sb_sampFreq.setValue(10000) self.sb_sampFreq.valueChanged.connect(lambda: self.refreshUI(1, 'sb_sampFreq', self.sb_sampFreq.value())) hbox4.addWidget(self.sb_sampFreq) # Radiobutton Continuous Measurement self.rb_cont = QRadioButton("Continuous") self.rb_cont.setChecked(True) self.rb_cont.toggled.connect(lambda: self.refreshUI(2, self.rb_cont, self.rb_finite)) hbox5.addWidget(self.rb_cont) # Radiobutton Finite Measurement self.rb_finite = QRadioButton("Finite") self.rb_finite.toggled.connect(lambda: self.refreshUI(2, self.rb_finite, self.rb_cont)) hbox5.addWidget(self.rb_finite) # Measurement duration QSpinBox self.duration = QSpinBox(self) self.duration.setMinimum(0) self.duration.setMaximum(600) self.duration.setValue(300.0) self.duration.valueChanged.connect(lambda: self.refreshUI(1, 'duration', self.duration.value())) hbox4.addWidget(self.duration) # ## Button GroupBox: # Group contains: # - Start button # - Stop button # - ProgressBar buttonGroup = QGroupBox("Control") hbox6 = QHBoxLayout() hbox11 = QHBoxLayout() vbox3 = QVBoxLayout() vbox3.addLayout(hbox6) vbox3.addStretch(1) vbox3.addLayout(hbox11) vbox3.addStretch(1) buttonGroup.setLayout(vbox3) # Start button self.startButton = QPushButton("Start", self) self.startButton.clicked.connect(self.startBtn) hbox6.addWidget(self.startButton) # Stop button self.stopButton = QPushButton("Stop", self) self.stopButton.clicked.connect(self.stopBtn) hbox6.addWidget(self.stopButton) # Progress Bar self.progress = QProgressBar(self) self.progress.setAlignment(Qt.AlignHCenter) self.progress.setRange(0, 100) hbox11.addWidget(self.progress) # ## LCD display group: # Group contains widgets: # - LCD display green # - LCD display red lcdGroup = QGroupBox("Count rates") hbox7 = QHBoxLayout() hbox8 = QHBoxLayout() vbox4 = QVBoxLayout() vbox4.addLayout(hbox7) vbox4.addLayout(hbox8) lcdGroup.setLayout(vbox4) hbox7.addWidget(self.label7) hbox7.addWidget(self.label8) # Green channel count rate self.green_lcd = QLCDNumber(self) self.green_lcd.setNumDigits(12) hbox8.addWidget(self.green_lcd) # Red channel count rate self.red_lcd = QLCDNumber(self) self.red_lcd.setNumDigits(12) hbox8.addWidget(self.red_lcd) # ## General Layout settings: self.centralBox = QGroupBox("Settings") self.setCentralWidget(self.centralBox) # self.centralWidget.setStyleSheet("QMainWindow {background: 'yellow';}"); # Arrange groups in grid: grid = QGridLayout() grid.addWidget(filesGroup, 0, 0, 1, 3) grid.addWidget(laserGroup, 1, 0, 2, 2) grid.addWidget(apdGroup, 1, 2, 1, 1) grid.addWidget(buttonGroup, 2, 2, 1, 1) grid.addWidget(lcdGroup, 3, 0, 1, 3) self.centralBox.setLayout(grid) def menueLayout(self): """ Here the file menue gets evoked. The actions are widgets, which get connected to the GetFileName method. It directs then to different functionality in a separate class. """ menubar = self.menuBar() fileMenue = menubar.addMenu('&File') fileMenue.addAction(self.loadApp) fileMenue.addAction(self.saveApp) fileMenue.addAction(self.convertData) fileMenue.addAction(self.setArraySize) fileMenue.addAction(self.closeApp) def getFilename(self): """ Select a file with qdialog. The return value of qdialog 'getOpenFileName' is list containing the filter information and the absolute path. @return: path """ start = 'C:/Users/Karoline2' path = QFileDialog.getOpenFileName(None, 'Select file', start) return path[0] def getDirectory(self): """ Select a directory with qdialog. """ start = 'C:/Users/Karoline2' path = QFileDialog.getExistingDirectory(None, 'Select directory', start, QFileDialog.ShowDirsOnly) return path def getFileLocation(self): path = self.getDirectory() self._location.setText(path) def loadDict(self): """ Load a settings dict from a '*.p' file. """ path = self.getFilename() new_dict = self._files.loadSetsDict(path) if new_dict is not None: self._dict._a.update(new_dict) self.refreshUI(3, self._dict._a, 0) self.statusBar.showMessage('Settings updated!') else: self.statusBar.showMessage('No valid settings dictionary in that file!') def closeApplication(self): """Close the app and animation window via file menue.""" choice = QMessageBox.question(self, 'Quit!', 'Really quit session?', QMessageBox.Yes | QMessageBox.No) if choice == QMessageBox.Yes: try: self._anim.__del__() except: pass sys.exit(0) else: pass def closeEvent(self, event): """Close also the animation window when the red 'X' button is pressed.""" try: self._anim.__del__() except: pass sys.exit(0) def refreshUI(self, changeType, changeKey, value): """ This is the first connection to the widgets. Here the widgets identify by changeType (their type) and changeKey (individual key), and pass a value. The values can only be applied if the event variable self._running is set to False. Changes are processed in refresher.refreshUI method, which returns a whole new dictionary. @param changeType: str @param changeKey: str @param value: int or float """ if self._running.is_set(): self.statusBar.showMessage("Please don't change parameters during measurement. Stop and restart with new settings.") else: self._dict._a = self._r.refreshUI(changeType, changeKey, value) self.refreshAll() def refreshRadioButton(self): """The radio buttons need a setChecked update, hence the extra method.""" state = self._dict._a["Radio"] if state == 0: self.rb_cont.setChecked(True) else: self.rb_finite.setChecked(True) def refreshAll(self): """All the widgets get updated with new values.""" self.sld_red.setValue(self._dict._a["lpower red"]) self.sld_green.setValue(self._dict._a["lpower green"]) self.sb_red.setValue(self._dict._a["lpower red"]) self.sb_green.setValue(self._dict._a["lpower green"]) self.sb_sampFreq.setValue(self._dict._a["laser frequency"]) self.duration.setValue(self._dict._a["Duration"]) self.refreshRadioButton() self.sld_percentage.setValue(self._dict._a["laser percentageG"]) self.sb_percentG.setValue(self._dict._a["laser percentageG"]) self.sb_percentR.setValue(self._dict._a["laser percentageR"]) def startBtn(self): """ Set the flag of '_running' to True and close all active (additional) windows. Then start the processes. If users click on start while the measurement is already running, a message 'Already running' is displayed. """ if not self._running.is_set(): self._running.set() # try to close animation and timetrace window # if timetrace does not close reliably, it could # cause problems try: plt.close('all') except: pass self.startProcesses() else: self.statusBar.showMessage("Already running!") def finalLocation(self): """ Calls the hdf mask, from which the sample name gets retrieved. Combined with actual date and time, it creates a new folder in the 'location' directory. Measurements settings and hdf info get saved into that new folder as .p and .txt files. If the hdfmask window is not exited by 'save', the measurement will be canceled. @return: str """ if self._dict._a["Radio"] == 0: new_folder = 'Cont' self.statusBar.showMessage("You are measuring in 'continuous' mode. The data will not get saved!") elif self._dict._a["Radio"] == 1: if self._location.text(): new_folder = self._files.saveRawData(self._location.text(), self._dict._a) if not new_folder: return 0 else: self.statusBar.showMessage('Please select a file directory!') new_folder = 0 return new_folder def startProcesses(self): """Get folder and start all processes and threads.""" self._new_folder = self.finalLocation() if self._new_folder: pass else: self.statusBar.showMessage('Please select a file location with the "Browse" button or save specs.') self._running.clear() return # Initialize processes and waiter thread self._duration = self._dict._a["Duration"] self._counter2 = libs.Counter.Counter(self._running, self._dataQ2, self._readArraySize, self._semaphore, 2) self._counter1 = libs.Counter.Counter(self._running, self._dataQ1, self._readArraySize, self._semaphore, 1) self._laser = libs.Laser.Laser(self._running, self._dict._a, self._semaphore) self._anim = libs.Animation.Animation(self._animDataQ1, self._animDataQ2, self.signal) self._dataProcesser1 = libs.DataProcesser.DataProcesser(self._dataQ1, self._animDataQ1, self._readArraySize, 1, self._new_folder) self._dataProcesser2 = libs.DataProcesser.DataProcesser(self._dataQ2, self._animDataQ2, self._readArraySize, 2, self._new_folder) self.statusBar.showMessage("Started!") self._anim.run() self._u = Thread(target=self.waiter, args=(), name='iterator', daemon=True) # Starting all processes and threads self._counter2.start() self._counter1.start() self._laser.start() self._u.start() self._dataProcesser1.start() self._dataProcesser2.start() self._anim.animate() # this command is vicious, it seems everything following # it gets delayed or not executed at all. Best always called last. def waiter(self): """ Illumination and APDs acquire the semaphore after initialization of tasks, the waiter waits for the semaphore to have its internal counter down to zero (when als tasks are ready). Only then the waiter proceeds and does actually nothing (mode = 0 --> continuous mode) or starts the progressBar and timing (mode 1 --> finite mode). In case of finite mode, the waiter stops the measurement after the duration elapses. In continuous mode, the measuremt must be stopped by the user In case of finite mode, the waiter stops the measurement after the duration elapses. In continuous mode, the measuremt must be stopped by the user. """ while self._semaphore.get_value() > 0: pass if self._dict._a["Radio"] == 0: self.progress.setRange(0, 0) else: # duration = self._dict._a["Duration"] duration_iter = np.arange(self._duration) self.progress.setRange(0, self._duration) for sec in duration_iter: time.sleep(1) self.signal.measurementProgress.emit(sec) if not self._running.is_set(): break else: self.signal.stopMeasurement.emit() @pyqtSlot(int) def setProgressBar(self, i): """ Setting the progressbar, it gets called solely by a pyqtSignal from the waiter thread. @param i: int """ self.progress.setValue(i) @pyqtSlot(list) def displayRatesOnLCD(self, x): """ Setting the lcd numbers with the count rates, it gets called solely by a pyqtSignal from the animation class. """ self.red_lcd.display(x[1]) self.green_lcd.display(x[0]) @pyqtSlot() def warnPopUp(self): """ Called from Animation if the count rate of one of the APDs is higher than 15MHz (15Mc/s). It pops up a message window, informing the user. Currently no stop mechanism is included, so the user has to stop the measurement mechanically. """ msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("APD count should not exceed 15 MHz!\nStop the measurement, check APDs and sample.") msg.setWindowTitle("APD Warning") msg.exec() def changeArraySize(self): answer = self._changeRA.showDialog() if answer is None: pass else: self._readArraySize = answer msg = 'The read array size is now {}'.format(self._readArraySize) self.statusBar.showMessage(msg) print(answer, self._readArraySize) @pyqtSlot() def stopBtn(self): """ Try to stop animation and join all the processes/threads. Extensive checking can be shortened. """ if self._running.is_set(): self._running.clear() self._anim.anim._stop() self.progress.setRange(0, 1) while not self._semaphore.get_value() == 3: pass # joining self.statusBar.showMessage("Stopped! Please wait while data is being processed.") self._laser.join(timeout=3.0) self._u.join(timeout=3.0) self._counter1.join(timeout=5.0) self._counter2.join(timeout=5.0) self._dataProcesser2.join(timeout=5.0) self._dataProcesser1.join(timeout=5.0) # extensive checking for joining check = 0 if self._dataProcesser1.is_alive(): print("DataProcesser 1 did not join.") del self._dataProcesser1 check += 1 if self._dataProcesser2.is_alive(): print("DataProcesser 2 did not join.") del self._dataProcesser2 check += 1 if self._counter1.is_alive(): print("Counter 1 did not join.") del self._counter1 check += 1 if self._counter2.is_alive(): print("Counter 2 did not join.") del self._counter2 check += 1 if self._u.is_alive(): print("Waiter thread did not join.") del self._u check += 1 if self._laser.is_alive(): print("Laser did not join.") del self._laser check += 1 if not check: print("All workers have joined.") # Print the timetrace of the data, is also saved as *.png into the data folder if not self._new_folder == 'Cont': self._timetrace.doThings(self._new_folder) self._files.convertToPhotonHDF5(self._new_folder, self.signal) # Unfortunately there is no other way than deleting the queues # If not done so, the rest data will be shown in the next measurement # instead of the new data. del self._animDataQ1, self._animDataQ2 self._animDataQ1 = mpQueue() self._animDataQ2 = mpQueue() self.statusBar.showMessage("Stopped and idle!") else: self.statusBar.showMessage("Already stopped or not running at all.")
from multiprocessing import Semaphore, Process from time import sleep import os #创建信号量 sem = Semaphore(3) def fun(): print("%d 想执行事件" % os.getpid()) sem.acquire() print("%d 执行想执行事件" % os.getpid()) sleep(3) print("%d 事件执行完毕" % os.getpid()) jobs = [] #创建5个进程 消耗5个信号量 不够则阻塞 for i in range(5): p = Process(target=fun) jobs.append(p) p.start() #又添加三个信号量 不再阻塞 for i in range(3): sleep(5) sem.release() # 增加一个信号量 #关闭进程 for i in jobs: i.join() #查看信号量 print("信号量剩余 %d" % sem.get_value())
'''semaphore related options''' from multiprocessing import Semaphore, Process from time import sleep import os #创建信号量 sem = Semaphore(3) def fun(): print("%d 执行事件" % os.getpid()) sem.acquire() #消耗一个信号量 print('%d 拿到信号开始执行事件' % os.getpid()) sleep(3) print('%d 事件执行完毕' % os.getpid()) sem.release() jobs = [] for i in range(5): p = Process(target=fun) jobs.append(p) p.start() for i in jobs: i.join() print("剩余的信号量为:", sem.get_value())
class BackgroundReportService(BackgroundMonitor, AsyncManagerMixin): def __init__(self, task, async_enable, metrics, flush_frequency, flush_threshold): super(BackgroundReportService, self).__init__(task=task, wait_period=flush_frequency) self._flush_threshold = flush_threshold self._exit_event = TrEvent() self._queue = TrQueue() self._queue_size = 0 self._res_waiting = Semaphore() self._metrics = metrics self._storage_uri = None self._async_enable = async_enable def set_storage_uri(self, uri): self._storage_uri = uri def set_subprocess_mode(self): if isinstance(self._queue, TrQueue): self._write() self._queue = PrQueue() if isinstance(self._exit_event, TrEvent): self._exit_event = SafeEvent() super(BackgroundReportService, self).set_subprocess_mode() def stop(self): if not self.is_subprocess() or self.is_subprocess_alive(): self._exit_event.set() super(BackgroundReportService, self).stop() def flush(self): self._queue_size = 0 if not self.is_subprocess() or self.is_subprocess_alive(): self._event.set() def add_event(self, ev): self._queue.put(ev) self._queue_size += 1 if self._queue_size >= self._flush_threshold: self.flush() def daemon(self): while not self._exit_event.wait(0): self._event.wait(self._wait_timeout) self._event.clear() self._res_waiting.acquire() self._write() # wait for all reports if self.get_num_results() > 0: self.wait_for_results() self._res_waiting.release() # make sure we flushed everything self._async_enable = False self._res_waiting.acquire() self._write() if self.get_num_results() > 0: self.wait_for_results() self._res_waiting.release() def _write(self): if self._queue.empty(): return # print('reporting %d events' % len(self._events)) events = [] while not self._queue.empty(): try: events.append(self._queue.get()) except Empty: break res = self._metrics.write_events(events, async_enable=self._async_enable, storage_uri=self._storage_uri) if self._async_enable: self._add_async_result(res) def send_all_events(self, wait=True): self._write() if wait and self.get_num_results() > 0: self.wait_for_results() def events_waiting(self): if not self._queue.empty(): return True if not self.is_alive(): return False return not self._res_waiting.get_value()
pids = set() q = Queue() # Cream el pool de procesos (pre-fork) for i in range(min_processos): sem_totals.release() p = Process(target=run_server, args=(q, )) p.start() pids.add(p.pid) #print "Nou proces: ", p.pid print "\nhttp://%s:%s\n" % (host, port) while True: # controlam amb semàfors que el nombre de processos no surti dels límits establerts sem_lliures = sem_totals.get_value() - sem_actius.get_value() #~ print "Lliures:", sem_lliures while (sem_totals.get_value() < min_processos) or ( (sem_totals.get_value() < max_processos) and (sem_lliures < min_processos_lliures)): #~ print "Totals:", sem_totals.get_value() sem_totals.release() p = Process(target=run_server, args=(q, )) # proces nou p.start() pids.add(p.pid) print "Nou proces:", p.pid pid = q.get(True) # espera pids.remove(pid) print "Acaba:", pid
from multiprocessing import Process, Semaphore from time import sleep import os sem = Semaphore(3) def fun(): print("%d 想执行的事件" % os.getpid()) #消耗一个信号量 sem.acquire() print("%d 执行事件..." % os.getpid()) sleep(3) print("%d 执行完毕" % os.getpid()) sem.release() #执行完成后添加一个信号量 jobs = [] for i in range(5): p = Process(target=fun) jobs.append(p) p.start() for i in jobs: i.join() print("sem:", sem.get_value())
#!/usr/bin/python3 from multiprocessing import Semaphore, Pool import os import time semaphore = Semaphore(1) def worker_process(): print(id(semaphore)) semaphore.release() #with semaphore: print("Process pid : (%s) " % os.getpid()\ ,'parents pid : (%s)' % os.getppid()) time.sleep(3) #print("Process (%s) ended" % os.getpid()) if __name__ == '__main__': print(id(semaphore)) pool = Pool(5) for i in range(0, 10): pool.apply_async(worker_process) pool.close() pool.join() print('main process pid : %s' % os.getpid()) print("Main Process ended") print(semaphore.get_value()) print(id(semaphore))
#!/usr/bin/python from multiprocessing import Semaphore sem = Semaphore() i = 0 while True: i += 1 if i % 10000 == 0: print sem.get_value() try: sem.release() except: print `sem.get_value()` raise
class SharedExclusiveLock(object): def __init__(self, maxreaders=120): # Linux max semaphore sets is 120 self.max = 120 self._reader = Semaphore(120) self._writer = Semaphore(1) self._sleeping = Event() # Does this process hold the write? self.localwrite = False self.thread_id = currentThread() self.create_methods() def after_fork(obj): obj._reader._after_fork() obj._writer._after_fork() obj._sleeping._after_fork() register_after_fork(self, after_fork) def create_methods(self): self.acquire = self._reader.acquire self.release = self._reader.release @property def ismine(self): return self.localwrite and (currentThread() == self.thread_id) # you can nest write calls def wait_noreaders(self): if self.ismine: return while self._reader.get_value() < self.max: self._sleeping.set() # twiddle the futex self._sleeping.wait() @contextmanager def writing(self): if self.ismine: yield else: self.wait_noreaders() self._writer.acquire() self.localwrite = True yield self.localwrite = False self._writer.release() def __enter__(self, blocking=True, timeout=None): # prevent writer starvation if self.ismine: return else: self._reader.acquire() def __exit__(self, *args): if self.ismine: return else: self._reader.release() if self._sleeping.is_set(): # twiddle the futex self._sleeping.clear() def __getstate__(self): assert_spawning(self) r = self._reader._semlock w = self._writer._semlock reader = Popen.duplicate_for_child(r.handle), r.kind, r.maxvalue writer = Popen.duplicate_for_child(w.handle), w.kind, w.maxvalue return (reader, writer) def __setstate__(self, state): reader, writer = state self._reader = SemLock._rebuild(*reader) self._writer = SemLock._rebuild(*writer)
*可以使用obj.value直接打印共享内存中的字节串 2.信号量(信号灯集) 【1】通信原理:给定一个数量对多个进程可见.多个进程都可以操作该数量增减, 并根据数量值决定自己的行为 【2】实现方法: from multiprocessing import Semaphore sem = Semaphore(num) 功能:创建信号量对象 参数:信号量的初始值 返回值:信号量对象 sem.acquire()将信号量减1 当信号量为0时阻塞 sem.release()将信号量加1 sem.get_value()获取信号量数量 二.线程编程(Thread) 1.什么是线程 【1】线程被称为轻量级的进程 【2】线程也可以使用计算机多核资源,是多任务编程方式 【3】线程是系统分配内核的最小单位 【4】线程可以理解为进程的分支任务 2. 线程特征 【1】一个进程中可以包含多个线程 【2】线程也是一个运行行为,消耗计算机资源 【3】一个进程中的所有线程共享这个进程的资源 【4】多个线程之间的运行互不影响各自运行 【5】线程的创建和销毁消耗资源远小于进程 【6】各个线程也有自己的ID等特征 3.threading模块创建线程
pids = set() q = Queue() # Cream el pool de procesos (pre-fork) for i in range(min_processos): sem_totals.release() p = Process(target=run_server, args=(q,)) p.start() pids.add(p.pid) # print "Nou proces: ", p.pid print "\nhttp://%s:%s\n" % (host, port) while True: # controlam amb semàfors que el nombre de processos no surti dels límits establerts sem_lliures = sem_totals.get_value() - sem_actius.get_value() # ~ print "Lliures:", sem_lliures while (sem_totals.get_value() < min_processos) or ( (sem_totals.get_value() < max_processos) and (sem_lliures < min_processos_lliures) ): # ~ print "Totals:", sem_totals.get_value() sem_totals.release() p = Process(target=run_server, args=(q,)) # proces nou p.start() pids.add(p.pid) print "Nou proces:", p.pid pid = q.get(True) # espera pids.remove(pid) print "Acaba:", pid
#创建初始的信号量 sem = Semaphore(3) def fun(): print('%d 想执行事件'%os.getpid()) #消耗一个信号量 sem.acquire() print("%d 执行事件"%os.getpid()) sleep(3) print("%d 执行完毕"%os.getpid()) sem.release() jobs = [] for i in range(5): p = Process(target = fun) jobs.append(p) p.start() for i in jobs: i.join() print('Sem:',sem.get_value())
# -*- coding: utf-8 -*- __author__ = 'Ljian' from datetime import datetime import time import multiprocessing from multiprocessing import Semaphore, Process def proc(sem, interval): sem.acquire() try: print("Current process: %r, acquire, semaphore value: %r" % (multiprocessing.current_process().name, sem.get_value())) time.sleep(interval) finally: sem.release() print("Current process: %r, release, semaphore value: %r" % (multiprocessing.current_process().name, sem.get_value())) if __name__ == '__main__': sem = Semaphore(2) # 生成个信号量个数为2的,信号量对象 print(sem.get_value()) for i in range(4): Process(target = proc, args = (sem, i)).start()
import os #创建信号量 sem = Semaphore(3) def fun(): print("%d 想执行事件"%os.getpid()) #消耗一个信号量,有信号量则不阻塞 sem.acquire() print("%d执行想执行的事件"%os.getpid()) sleep(3) print("%d事件执行完毕"%os.getpid()) jobs = [] #5个进程每个需要消耗一个,但是现在只有3个 for i in range(5): p = Process(target = fun) jobs.append(p) p.start() #不够用了,所有又增加了3个量 for i in range(3): sleep(5) sem.release() #增加一个信号量 for i in jobs: i.join() print(sem.get_value()) #最后剩1个
from multiprocessing import Semaphore, Process, freeze_support import time def Worker(N, semaphore): print("Worker %i started." % N) time.sleep(N) semaphore.acquire() print("Worker %i exits." % N) if __name__=='__main__': freeze_support() semaphore = Semaphore(3) processes = [] start = time.time() for i in range(3): p = Process(target=Worker, args=(i, semaphore)) p.start() processes.append(p) while semaphore.get_value() > 0: pass end = time.time() while not semaphore.get_value() == 3: semaphore.release() print("Semaphore counter reached 0 after %f seconds" % (end - start))
if __name__ == '__main__': app = AWSApplication() print("Using queue: ", app.queue.url) active = True POOL_SIZE = max(CPU_COUNT - 1, 1) print("Pool size is ", POOL_SIZE) available_workers = Semaphore(POOL_SIZE) def on_worker_done(future): available_workers.release() with ProcessPoolExecutor(max_workers=POOL_SIZE) as process_pool: while (active): try: if (available_workers.get_value()): messages = app.queue.receive_messages( MaxNumberOfMessages=available_workers.get_value()) for message in messages: print(message.body) try: print("Creating worker") available_workers.acquire() fut = process_pool.submit(process_message, message.body) fut.add_done_callback(on_worker_done) except: print("Could not process message in pool.\n", message) continue
def func4(sec): print('start func4',os.getpid()) sleep(1) print('func4 acquire',sem.acquire()) sleep(sec) print('func4 release',sem.release()) l = [func1,func2,func3,func4] resulf = [] #观察四个进程的执行过程,和现象 for i in l: p = Process(target = i,args = (3,)) resulf.append(p) p.start() for i in resulf: i.join() print('last semaphore number:',sem.get_value()) print('process over')
from time import sleep import os #创建信号量 sem = Semaphore(3) def fun(): print('%d 想执行事件' % os.getpid()) #消耗一个信号量,有信号量则不阻塞 sem.acquire() print('%d执行想执行的事件'% os.getpid()) sleep(3) print('%d事件执行完毕' % os.getpid()) jobs = [] for i in range(5): p = Process(target = fun) jobs.append(p) p.start() for i in range(3): sleep(5) sem.release() #增加一个信号量 for i in jobs: i.join() print(sem.get_value())
from multiprocessing import Semaphore, Process from time import sleep import os # 创建信号量 # 服务程序最多允许3个进程同时执行事件 sem = Semaphore(3) def handle(): print("%d 想执行时间" % os.getpid()) # 想执行必须获取信号量 sem.acquire() print("%d 开始执行操作" % os.getpid()) sleep(3) print("%d 完成操作" % os.getpid()) sem.release() # 增加信号量 jobs = [] # 10个进程请求执行事件 for i in range(5): p = Process(target=handle) jobs.append(p) p.start() for i in jobs: i.join() print(sem.get_value()) # 获取信号量值
#!/usr/bin/python from multiprocessing import Semaphore sem = Semaphore() i = 0 while True: i += 1 if i % 10000 == 0: print sem.get_value() try: sem.release() except: print ` sem.get_value() ` raise
from multiprocessing import Semaphore, Process from time import sleep import os #创建信号量 sem = Semaphore(3) def fun(): print("%d 想执行事件" % os.getpid()) #想执行事件必须得到信号量资源 sem.acquire() print('%d 抢到了一个信号量,可以执行操作' % os.getpid()) sleep(3) print("%d 执行完事件后再增加信号量" % os.getpid()) sem.release() jobs = [] for i in range(5): p = Process(target=fun) jobs.append(p) p.start() for p in jobs: p.join() #获取信号量数量 print('获取信号量数量:', sem.get_value())