思绪来得快 也去得快 偶尔在这里停留

Blog

首页博客
22
Nov
0

maven配置多个配置文件

使用打包命令或是直接在maven的选择框profiles里选择使用哪个环境

开发环境打包命令
mvn clean install -P dev

测试环境打包命令
mvn clean install -P test

生产环境打包命令
mvn clean install -P formal

pom.xml配置
根节点:
<profiles>

<profile>
  <id>test</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <properties>
    <build.profile.id>test</build.profile.id>
  </properties>
</profile>
<profile>
  <id>develop</id>
  <properties>
    <build.profile.id>develop</build.profile.id>
  </properties>
</profile>
<profile>
  <id>prod</id>
  <properties>
    <build.profile.id>prod</build.profile.id>
  </properties>
</profile>

</profiles>

build节点:
<build>

  <filters>
      <filter>src/app-${build.profile.id}.properties</filter>
  </filters>
  <resources>
      <resource>
          <filtering>true</filtering>
          <!--加上filter会过滤该资源路径中的文件-->
          <directory>${project.basedir}/src/main/resources</directory>
      </resource>
  </resources>

</build>

配置文件Resources目录下:

System.properties 配置文件
app.mode=${app.mode}
app-develop.properties 开发配置文件
app.mode=develop
app-formal.properties 生产配置文件
app.mode=formal
app.test.properties 测试配置文件
app.mode=test

程序中获取:
import java.util.Properties
import java.io.FileInputStream

def loadProperties():Unit = {

val properties = new Properties()
val path = Thread.currentThread().getContextClassLoader.getResource("System.properties").getPath //文件要放到resource文件夹下
properties.load(new FileInputStream(path))
println(properties.getProperty("app.mode"))//读取键为ddd的数据的值
println(properties.getProperty("app.mode","没有值"))//如果ddd不存在,则返回第二个参数
properties.setProperty("app.mode","123")//添加或修改属性值

}

22
Nov
0

python后台程序实现

方法1 使用nohup命令
nohup python work.py >my.log &

方法2 python-daemon
安装python-daemon

pip install python-daemon

编写入口程序
use_daemon.py

-- coding:utf-8 --

import daemon
from work import work
with daemon.DaemonContext():
work()

19
Nov
0

python模板注释

每次设置文件头麻烦 下次重装系统直接来复制

file -> settings -> editor -> file and code templetes -> python script

!/usr/bin/python3.6.7

-- coding: utf-8 --

@Time    : ${DATE} ${TIME}

@Author  : ${USER}

@Desc : ==============================================

Life is Short I Use Python!!!                      ===

If this runs wrong,don't ask me,I don't know why;  ===

If this runs right,thank god,and I don't know why. ===

Maybe the answer,my friend,is blowing in the wind. ===

======================================================

@Project : ${PROJECT_NAME}

@FileName: ${NAME}.py

@Software: ${PRODUCT_NAME}${PRODUCT_VERSION}

19
Oct
0

信号量Semaphore和互斥锁Mutex和condition对象和event对象

信号量

from multiprocessing import Process,Semaphore
import time,random

def go_wc(sem,user):
    sem.acquire()
    print('%s 占到一个茅坑' %user)
    time.sleep(random.randint(0,3)) #模拟每个人拉屎速度不一样,0代表有的人蹲下就起来了
    sem.release()

if __name__ == '__main__':
    sem=Semaphore(3)
    p_l=[]
    for i in range(10):
        p=Process(target=go_wc,args=(sem,'user%s' %i,))
        p.start()
        p_l.append(p)

    for i in p_l:
        i.join()
    print('============》')

互斥锁

from multiprocessing import Process, Lock
from time import sleep

def tack():
    search()
    lock.acquire()    # 上锁
    sleep(0.01)
    lock.release()    # 释放
 
 
if __name__ == '__main__':
    lock = Lock()    # 实例化一把锁
 
    for i in range(100):    # 模拟并发100个客户端抢票
        p =Process(target=tack)
        p.start()

condition对象

所谓条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据。
它使用Condition类来完成,由于它也可以像锁机制那样用,所以它也有acquire方法和release方法,而且它还有wait,notify,notifyAll方法。

一个简单的生产消费者模型,通过条件变量的控制产品数量的增减,调用一次生产者产品就是+1,调用一次消费者产品就会-1.
使用 Condition 类来完成,由于它也可以像锁机制那样用,所以它也有 acquire 方法和 release 方法,而且它还有
wait, notify, notifyAll 方法。

import threading
import queue, time, random
 
# 产品类
class Goods:
    def __init__(self):
        self.count = 0
 
    def add(self, num=1):
        self.count += num
 
    def sub(self):
        if self.count >= 0:
            self.count -= 1
 
    def empty(self):
        return self.count <= 0
 
# 生产者
class Producer(threading.Thread):
 
    def __init__(self, condition, goods, sleeptime=1):
        threading.Thread.__init__(self)
        self.cond = condition
        self.goods = goods
        self.sleeptime = sleeptime
 
    def run(self):
        cond = self.cond
        goods = self.goods
        while True:
            # 锁住资源
            cond.acquire()
            goods.add()
            print("产品数量:", goods.count, "生产者线程")
            # 唤醒所有等待的线程 -> 其实就是唤醒消费者进程
            cond.notifyAll()
            # 解锁资源
            cond.release()
            time.sleep(self.sleeptime)
 
# 消费者
class Consumer(threading.Thread):
    def __init__(self, condition, goods, sleeptime=2):
        threading.Thread.__init__(self)
        self.cond = condition
        self.goods = goods
        self.sleeptime = sleeptime
 
    def run(self):
        cond = self.cond
        goods = self.goods
        while True:
            time.sleep(self.sleeptime)
            # 锁住资源
            cond.acquire()
            # 如无产品则让线程等待
            while goods.empty():
                cond.wait()
            goods.sub()
            print("产品数量:", goods.count, "消费者线程")
            # 解锁资源<br>            
            cond.release()
g = Goods() 
c = threading.Condition() 
pro = Producer(c, g) 
pro.start() 
con = Consumer(c, g) 
con.start()

event 对象

event 对象最好单次使用,就是说,你创建一个 event 对象,让某个线程等待这个对象,
一旦这个对象被设置为真,你就应该丢弃它。尽管可以通过 clear() 方法来重置 event 对
象,但是很难确保安全地清理 event 对象并对它重新赋值。很可能会发生错过事件、死锁
或者其他问题(特别是,你无法保证重置 event 对象的代码会在线程再次等待这个 event对象之前执行)。如果一个线程需要不停地重复使用 event 对象,你最好使用 Condition
对象来代替。下面的代码使用 Condition 对象实现了一个周期定时器,每当定时器超时的
时候,其他线程都可以监测到

import threading
import time
 
class PeriodicTimer:
    def __init__(self, interval):
        self._interval = interval
        self._flag = 0
        self._cv = threading.Condition()
 
    def start(self):
        t = threading.Thread(target=self.run)
        t.daemon = False
        t.start()
 
    def run(self):
        # Run the timer and notify waiting threads after each interval
        while True:
            time.sleep(self._interval)
            with self._cv:
                self._flag ^= 1
                self._cv.notify_all()
 
    def wait_for_tick(self):
        # wait for the next tick of the timer
 
        with self._cv:
            last_flag = self._flag
            while last_flag == self._flag:
                self._cv.wait()
 
ptimer = PeriodicTimer(2)
ptimer.start()
 
def countdown(nticks):
    while nticks > 0:
        ptimer.wait_for_tick()
        print('T-minus', nticks)
        nticks -= 1
 
def countup(last):
    n = 0
    while n < last:
        ptimer.wait_for_tick()
        print('Counting', n)
        n += 1
 
 
threading.Thread(target=countdown, args=(10,)).start()
threading.Thread(target=countup, args=(10,)).start()
18
Oct
0

简单的调试以及异常触发显示行号记录行号的类

实际上是HOOK了system的Assert,在 ZytDebug.pas里,通过命令行输入 debug 还是 log。

/Debug 在错误处调用 Assert 可以显示行号??

ZytDebug.pas 有三个函数

procedure Debug(const S: string);

procedure DebugEnter(const S: string);

procedure DebugLeave(const S: string);

可以在 IDE debug窗口中中形成类似的缩进的效果。

有两个单元 ZytDebug.pas和Zytlogger.pas。

Zytlogger.pas 仅对 PFeng 的日之类进行了接口封装,自创建自销毁。仅两个函数:

1: function ZytLog:IZytLogger; overload;

2: function ZytLog(LogDir: AnsiString;LogShower:TComponent=nil):IZytLogger;overload;

直接调用即可。第二个可以指定日志显示容器载体。

希望对初学者有帮助。

支持delphibbs 重开。

附件为简单测试。

TestAssert.zip