时间:2021-07-01 10:21:17 帮助过:15人阅读
同进程的一样,Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1;调用release() 时内置计数器+1;计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。
实例:(同时只有5个线程可以获得semaphore,即可以限制最大连接数为5):
- <span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> Thread,Semaphore,current_thread
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time,random
- sm</span>=Semaphore(5<span style="color: #000000">)
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> task():
- with sm:
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s is laing</span><span style="color: #800000">‘</span> %<span style="color: #000000">current_thread().getName())
- time.sleep(random.randint(</span>1,3<span style="color: #000000">))
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(20<span style="color: #000000">):
- t</span>=Thread(target=<span style="color: #000000">task)
- t.start()</span>
与进程池是完全不同的概念,进程池Pool(4),最大只能产生4个进程,而且从头到尾都只是这四个进程,不会产生新的,而信号量是产生一堆线程/进程
同进程的一样,线程的一个关键特性是每个线程都是独立运行且状态不可预测。如果程序中的其 他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就会变得非常棘手。为了解决这些问题,我们需要使用threading库中的Event对象。 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生。在 初始情况下,Event对象中的信号标志被设置为假。如果有线程等待一个Event对象, 而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真。一个线程如果将一个Event对象的信号标志设置为真,它将唤醒所有等待这个Event对象的线程。如果一个线程等待一个已经被设置为真的Event对象,那么它将忽略这个事件, 继续执行
- <span style="color: #000000">event.isSet():返回event的状态值;
- event.wait():如果 event.isSet()</span>==<span style="color: #000000">False将阻塞线程;
- event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
- event.clear():恢复event的状态值为False。
- </span>
例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作
- <span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> Thread,Event,current_thread
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time
- event</span>=<span style="color: #000000">Event()
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> check():
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">checking MySQL...</span><span style="color: #800000">‘</span><span style="color: #000000">)
- time.sleep(</span>5<span style="color: #000000">)
- event.set()
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> conn():
- count</span>=1
- <span style="color: #0000ff">while</span> <span style="color: #0000ff">not</span><span style="color: #000000"> event.is_set():
- </span><span style="color: #0000ff">if</span> count > 3<span style="color: #000000">:
- </span><span style="color: #0000ff">raise</span> TimeoutError(<span style="color: #800000">‘</span><span style="color: #800000">超时</span><span style="color: #800000">‘</span><span style="color: #000000">)
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s try to connect MySQL time %s</span><span style="color: #800000">‘</span> %<span style="color: #000000">(current_thread().getName(),count))
- event.wait(</span>1<span style="color: #000000">)
- count</span>+=1
- <span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s connected MySQL</span><span style="color: #800000">‘</span> %<span style="color: #000000">current_thread().getName())
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- t1</span>=Thread(target=<span style="color: #000000">check)
- t2</span>=Thread(target=<span style="color: #000000">conn)
- t3</span>=Thread(target=<span style="color: #000000">conn)
- t4</span>=Thread(target=<span style="color: #000000">conn)
- t1.start()
- t2.start()
- t3.start()
- t4.start()</span>
定时器,指定n秒后执行某操作
- <span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> Timer
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> hello(name):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">"</span><span style="color: #800000">hello, world %s </span><span style="color: #800000">"</span> %<span style="color: #000000">name)
- t </span>= Timer(3, hello,args=(<span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span><span style="color: #000000">,))
- t.start() </span><span style="color: #008000">#</span><span style="color: #008000"> after 1 seconds, "hello, world" will be printed</span>
queue队列 :使用import queue,用法与进程Queue一样
- <span style="color: #0000ff">import</span><span style="color: #000000"> queue
- q</span>=queue.Queue(3) <span style="color: #008000">#</span><span style="color: #008000">队列:先进先出</span>
- <span style="color: #000000">
- q.put(</span>1<span style="color: #000000">)
- q.put(</span>2<span style="color: #000000">)
- q.put(</span>3<span style="color: #000000">)
- </span><span style="color: #008000">#</span><span style="color: #008000"> q.put(4)</span>
- <span style="color: #008000">#</span><span style="color: #008000"> q.put_nowait(4)</span>
- <span style="color: #008000">#</span><span style="color: #008000"> q.put(4,block=False)</span>
- <span style="color: #000000">
- q.put(</span>4,block=True,timeout=3<span style="color: #000000">)
- </span><span style="color: #008000">#</span><span style="color: #008000"> print(q.get())</span>
- <span style="color: #008000">#</span><span style="color: #008000"> print(q.get())</span>
- <span style="color: #008000">#</span><span style="color: #008000"> print(q.get())</span>
- <span style="color: #000000">
- q</span>=queue.LifoQueue(3) <span style="color: #008000">#</span><span style="color: #008000">堆栈:后进先出</span>
- <span style="color: #000000">
- q.put(</span>1<span style="color: #000000">)
- q.put(</span>2<span style="color: #000000">)
- q.put(</span>3<span style="color: #000000">)
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
- q</span>=queue.PriorityQueue(3) <span style="color: #008000">#</span><span style="color: #008000">优先级队列</span>
- <span style="color: #000000">
- q.put((</span>10,<span style="color: #800000">‘</span><span style="color: #800000">a</span><span style="color: #800000">‘</span><span style="color: #000000">))
- q.put((</span>-3,<span style="color: #800000">‘</span><span style="color: #800000">b</span><span style="color: #800000">‘</span><span style="color: #000000">))
- q.put((</span>100,<span style="color: #800000">‘</span><span style="color: #800000">c</span><span style="color: #800000">‘</span><span style="color: #000000">))
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(q.get())
- </span><span style="color: #0000ff">print</span>(q.get())
#提交任务的两种方式:
#同步调用:提交完任务后,就在原地等待,等待任务执行完毕,拿到任务的返回值,才能继续下一行代码,导致程序串行执行
#异步调用+回调机制:提交完任务后,不在原地等待,任务一旦执行完毕就会触发回调函数的执行, 程序是并发执行
#进程的执行状态:
#阻塞
#非阻塞
# from multiprocessing import Pool
- <span style="color: #0000ff">from</span> concurrent.futures <span style="color: #0000ff">import</span><span style="color: #000000"> ThreadPoolExecutor,ProcessPoolExecutor
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time,random,os
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> task(n):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s is ruuning</span><span style="color: #800000">‘</span> %<span style="color: #000000">os.getpid())
- time.sleep(random.randint(</span>1,3<span style="color: #000000">))
- </span><span style="color: #0000ff">return</span> n**2
- <span style="color: #0000ff">def</span><span style="color: #000000"> handle(res):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">handle res %s</span><span style="color: #800000">‘</span> %<span style="color: #000000">res)
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- </span><span style="color: #008000">#</span><span style="color: #008000">同步调用</span>
- <span style="color: #000000">
- pool</span>=ProcessPoolExecutor(2<span style="color: #000000">)
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(5<span style="color: #000000">):
- res</span>=<span style="color: #000000">pool.submit(task,i).result()
- </span><span style="color: #008000">#</span><span style="color: #008000"> print(res)</span>
- <span style="color: #000000">
- handle(res)
- pool.shutdown(wait</span>=<span style="color: #000000">True)
- </span><span style="color: #008000">#</span><span style="color: #008000"> pool.submit(task,33333)</span>
- <span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">主</span><span style="color: #800000">‘</span><span style="color: #000000">)
- </span>
- <span style="color: #0000ff">from</span> concurrent.futures <span style="color: #0000ff">import</span><span style="color: #000000"> ThreadPoolExecutor,ProcessPoolExecutor
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time,random,os
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> task(n):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s is ruuning</span><span style="color: #800000">‘</span> %<span style="color: #000000">os.getpid())
- time.sleep(random.randint(</span>1,3<span style="color: #000000">))
- </span><span style="color: #008000">#</span><span style="color: #008000"> res=n**2</span>
- <span style="color: #008000">#</span><span style="color: #008000"> handle(res)</span>
- <span style="color: #0000ff">return</span> n**2
- <span style="color: #0000ff">def</span><span style="color: #000000"> handle(res):
- res</span>=<span style="color: #000000">res.result()
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">handle res %s</span><span style="color: #800000">‘</span> %<span style="color: #000000">res)
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- </span><span style="color: #008000">#</span><span style="color: #008000">异步调用</span>
- <span style="color: #000000">
- pool</span>=ProcessPoolExecutor(2<span style="color: #000000">)
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(5<span style="color: #000000">):
- obj</span>=<span style="color: #000000">pool.submit(task,i)
- obj.add_done_callback(handle) </span><span style="color: #008000">#</span><span style="color: #008000">handle(obj)</span>
- <span style="color: #000000">
- pool.shutdown(wait</span>=<span style="color: #000000">True)
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">主</span><span style="color: #800000">‘</span>)
- <span style="color: #0000ff">from</span> concurrent.futures <span style="color: #0000ff">import</span><span style="color: #000000"> ThreadPoolExecutor
- </span><span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> current_thread
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> requests
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> get(url):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s GET %s</span><span style="color: #800000">‘</span> %<span style="color: #000000">(current_thread().getName(),url))
- response</span>=<span style="color: #000000">requests.get(url)
- time.sleep(</span>2<span style="color: #000000">)
- </span><span style="color: #0000ff">if</span> response.status_code == 200<span style="color: #000000">:
- </span><span style="color: #0000ff">return</span> {<span style="color: #800000">‘</span><span style="color: #800000">url</span><span style="color: #800000">‘</span>:url,<span style="color: #800000">‘</span><span style="color: #800000">content</span><span style="color: #800000">‘</span><span style="color: #000000">:response.text}
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> parse(res):
- res</span>=<span style="color: #000000">res.result()
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">parse:[%s] res:[%s]</span><span style="color: #800000">‘</span> %(res[<span style="color: #800000">‘</span><span style="color: #800000">url</span><span style="color: #800000">‘</span>],len(res[<span style="color: #800000">‘</span><span style="color: #800000">content</span><span style="color: #800000">‘</span><span style="color: #000000">])))
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- pool</span>=ThreadPoolExecutor(2<span style="color: #000000">)
- urls</span>=<span style="color: #000000">[
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.baidu.com</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.python.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- </span><span style="color: #800000">‘</span><span style="color: #800000">https://www.openstack.org</span><span style="color: #800000">‘</span><span style="color: #000000">,
- ]
- </span><span style="color: #0000ff">for</span> url <span style="color: #0000ff">in</span><span style="color: #000000"> urls:
- pool.submit(get,url).add_done_callback(parse)
- pool.shutdown(wait</span>=True)
单纯地切换反而会降低运行效率
协程:是单线程下的并发,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
总结协程特点:
必须在只有一个单线程里实现并发
修改共享数据不需加锁
用户程序里自己保存多个控制流的上下文栈
附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yield、greenlet都无法实现,就用到了gevent模块(select机制))
- <span style="color: #0000ff">import</span><span style="color: #000000"> time
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> consumer(res):
- </span><span style="color: #800000">‘‘‘</span><span style="color: #800000">任务1:接收数据,处理数据</span><span style="color: #800000">‘‘‘</span>
- <span style="color: #0000ff">pass</span>
- <span style="color: #0000ff">def</span><span style="color: #000000"> producer():
- </span><span style="color: #800000">‘‘‘</span><span style="color: #800000">任务2:生产数据</span><span style="color: #800000">‘‘‘</span><span style="color: #000000">
- res</span>=<span style="color: #000000">[]
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(10000000<span style="color: #000000">):
- res.append(i)
- </span><span style="color: #0000ff">return</span><span style="color: #000000"> res
- start</span>=<span style="color: #000000">time.time()
- </span><span style="color: #008000">#</span><span style="color: #008000">串行执行</span>
- <span style="color: #000000">
- res</span>=<span style="color: #000000">producer()
- consumer(res)
- stop</span>=<span style="color: #000000">time.time()
- </span><span style="color: #0000ff">print</span>(stop-<span style="color: #000000">start)
- </span>
- <span style="color: #0000ff">import</span><span style="color: #000000"> time
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> consumer():
- </span><span style="color: #800000">‘‘‘</span><span style="color: #800000">任务1:接收数据,处理数据</span><span style="color: #800000">‘‘‘</span>
- <span style="color: #0000ff">while</span><span style="color: #000000"> True:
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">consumer</span><span style="color: #800000">‘</span><span style="color: #000000">)
- x</span>=<span style="color: #0000ff">yield</span><span style="color: #000000">
- time.sleep(</span>100<span style="color: #000000">)
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> producer():
- </span><span style="color: #800000">‘‘‘</span><span style="color: #800000">任务2:生产数据</span><span style="color: #800000">‘‘‘</span><span style="color: #000000">
- g</span>=<span style="color: #000000">consumer()
- next(g)
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(10000000<span style="color: #000000">):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">producer</span><span style="color: #800000">‘</span><span style="color: #000000">)
- g.send(i)
- start</span>=<span style="color: #000000">time.time()
- </span><span style="color: #008000">#</span><span style="color: #008000">基于yield保存状态,实现两个任务直接来回切换,即并发的效果</span>
- <span style="color: #008000">#</span><span style="color: #008000">PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的.</span>
- <span style="color: #000000">
- producer()
- stop</span>=<span style="color: #000000">time.time()
- </span><span style="color: #0000ff">print</span>(stop-start) <span style="color: #008000">#
- </span>
如果我们在单个线程内有20个任务,要想实现在多个任务之间切换,使用yield生成器的方式过于麻烦(需要先得到初始化一次的生成器,然后再调用send。。。非常麻烦),而使用greenlet模块可以非常简单地实现这20个任务直接的切换
安装模块
- pip3 install greenlet
- <span style="color: #0000ff">from</span> greenlet <span style="color: #0000ff">import</span><span style="color: #000000"> greenlet
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> eat(name):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s eat 1</span><span style="color: #800000">‘</span> %<span style="color: #000000">name)
- time.sleep(</span>1000<span style="color: #000000">)
- g2.switch(</span><span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span><span style="color: #000000">)
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s eat 2</span><span style="color: #800000">‘</span> %<span style="color: #000000">name)
- g2.switch()
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> play(name):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s play 1</span><span style="color: #800000">‘</span> %<span style="color: #000000"> name)
- g1.switch() </span><span style="color: #008000">#</span><span style="color: #008000">可以在第一次switch时传入参数,以后都不需要</span>
- <span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s play 2</span><span style="color: #800000">‘</span> %<span style="color: #000000"> name)
- g1</span>=<span style="color: #000000">greenlet(eat)
- g2</span>=greenlet(play)
greenlet只是提供了一种比generator更加便捷的切换方式,当切到一个任务执行时如果遇到io,那就原地阻塞,仍然是没有解决遇到IO自动切换来提升效率的问题。
单线程里的这20个任务的代码通常会既有计算操作又有阻塞操作,我们完全可以在执行任务1时遇到阻塞,就利用阻塞的时间去执行任务2。。。。如此,才能提高效率,这就用到了Gevent模块。
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
#用法
- g1=gevent.spawn(func,1,,2,3,x=4,y=5<span style="color: #000000">)创建一个协程对象g1,spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat的
- g2</span>=<span style="color: #000000">gevent.spawn(func2)
- g1.join() </span><span style="color: #008000">#</span><span style="color: #008000">等待g1结束</span>
- <span style="color: #000000">
- g2.join() </span><span style="color: #008000">#</span><span style="color: #008000">等待g2结束</span>
- <span style="color: #008000">#</span><span style="color: #008000">或者上述两步合作一步:gevent.joinall([g1,g2])</span>
- <span style="color: #000000">
- g1.value</span><span style="color: #008000">#</span><span style="color: #008000">拿到func1的返回值</span>
- <span style="color: #0000ff">from</span> gevent <span style="color: #0000ff">import</span><span style="color: #000000"> monkey;monkey.patch_all()
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> gevent
- </span><span style="color: #0000ff">import</span><span style="color: #000000"> time
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> eat(name):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s eat 1</span><span style="color: #800000">‘</span> %<span style="color: #000000">name)
- </span><span style="color: #008000">#</span><span style="color: #008000"> gevent.sleep(3)</span>
- <span style="color: #000000">
- time.sleep(</span>3<span style="color: #000000">)
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s eat 2</span><span style="color: #800000">‘</span> %<span style="color: #000000">name)
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> play(name):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s play 1</span><span style="color: #800000">‘</span> %<span style="color: #000000"> name)
- </span><span style="color: #008000">#</span><span style="color: #008000"> gevent.sleep(2)</span>
- <span style="color: #000000">
- time.sleep(</span>3<span style="color: #000000">)
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">%s play 2</span><span style="color: #800000">‘</span> %<span style="color: #000000"> name)
- g1</span>=gevent.spawn(eat,<span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span><span style="color: #000000">)
- g2</span>=gevent.spawn(play,<span style="color: #800000">‘</span><span style="color: #800000">alex</span><span style="color: #800000">‘</span><span style="color: #000000">)
- </span><span style="color: #008000">#</span><span style="color: #008000"> gevent.sleep(1)</span>
- <span style="color: #008000">#</span><span style="color: #008000"> g1.join()</span>
- <span style="color: #008000">#</span><span style="color: #008000"> g2.join()</span>
- <span style="color: #000000">
- gevent.joinall([g1,g2])</span>
练习
通过gevent实现单线程下的socket并发(from gevent import monkey;monkey.patch_all()一定要放到导入socket模块之前,否则gevent无法识别socket的阻塞)
服务端
- <span style="color: #0000ff">from</span> gevent <span style="color: #0000ff">import</span><span style="color: #000000"> monkey,spawn;monkey.patch_all()
- </span><span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> current_thread
- </span><span style="color: #0000ff">from</span> socket <span style="color: #0000ff">import</span> *
- <span style="color: #0000ff">def</span><span style="color: #000000"> comunicate(conn):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">子线程:%s</span><span style="color: #800000">‘</span> %<span style="color: #000000">current_thread().getName())
- </span><span style="color: #0000ff">while</span><span style="color: #000000"> True:
- </span><span style="color: #0000ff">try</span><span style="color: #000000">:
- data</span>=conn.recv(1024<span style="color: #000000">)
- </span><span style="color: #0000ff">if</span> <span style="color: #0000ff">not</span> data:<span style="color: #0000ff">break</span><span style="color: #000000">
- conn.send(data.upper())
- </span><span style="color: #0000ff">except</span><span style="color: #000000"> ConnectionResetError:
- </span><span style="color: #0000ff">break</span><span style="color: #000000">
- conn.close()
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> server(ip,port):
- </span><span style="color: #0000ff">print</span>(<span style="color: #800000">‘</span><span style="color: #800000">主线程:%s</span><span style="color: #800000">‘</span> %<span style="color: #000000">current_thread().getName())
- server </span>=<span style="color: #000000"> socket(AF_INET, SOCK_STREAM)
- server.bind((ip,port))
- server.listen(</span>5<span style="color: #000000">)
- </span><span style="color: #0000ff">while</span><span style="color: #000000"> True:
- conn, addr </span>=<span style="color: #000000"> server.accept()
- </span><span style="color: #0000ff">print</span><span style="color: #000000">(addr)
- </span><span style="color: #008000">#</span><span style="color: #008000"> comunicate(conn)</span>
- <span style="color: #008000">#</span><span style="color: #008000"> t=Thread(target=comunicate,args=(conn,))</span>
- <span style="color: #008000">#</span><span style="color: #008000"> t.start()</span>
- <span style="color: #000000">
- spawn(comunicate,conn)
- server.close()
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- g</span>=spawn(server,<span style="color: #800000">‘</span><span style="color: #800000">127.0.0.1</span><span style="color: #800000">‘</span>, 8081<span style="color: #000000">)
- g.join()</span>
客户端
多线程并发多个客户端
- <span style="color: #0000ff">from</span> socket <span style="color: #0000ff">import</span> *
- <span style="color: #0000ff">from</span> threading <span style="color: #0000ff">import</span><span style="color: #000000"> current_thread,Thread
- </span><span style="color: #0000ff">def</span><span style="color: #000000"> client():
- client</span>=<span style="color: #000000">socket(AF_INET,SOCK_STREAM)
- client.connect((</span><span style="color: #800000">‘</span><span style="color: #800000">127.0.0.1</span><span style="color: #800000">‘</span>,8081<span style="color: #000000">))
- </span><span style="color: #0000ff">while</span><span style="color: #000000"> True:
- client.send((</span><span style="color: #800000">‘</span><span style="color: #800000">%s say hello</span><span style="color: #800000">‘</span> %current_thread().getName()).encode(<span style="color: #800000">‘</span><span style="color: #800000">utf-8</span><span style="color: #800000">‘</span><span style="color: #000000">))
- data</span>=client.recv(1024<span style="color: #000000">)
- </span><span style="color: #0000ff">print</span>(data.decode(<span style="color: #800000">‘</span><span style="color: #800000">utf-8</span><span style="color: #800000">‘</span><span style="color: #000000">))
- client.close()
- </span><span style="color: #0000ff">if</span> <span style="color: #800080">__name__</span> == <span style="color: #800000">‘</span><span style="color: #800000">__main__</span><span style="color: #800000">‘</span><span style="color: #000000">:
- </span><span style="color: #0000ff">for</span> i <span style="color: #0000ff">in</span> range(500<span style="color: #000000">):
- t</span>=Thread(target=<span style="color: #000000">client)
- t.start()</span>
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司。MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
1、数据库服务器:计算机
2、数据库管理软件:MySQL
3、数据库/库:文件夹
4、表:文件
5、记录:一个事物的一系列典型的特征:egon,male,18,oldgirl
6、数据:事物的特征,sex=‘male‘
#mysql就是一个基于socket编写的C/S架构的软件
#客户端软件
mysql自带:如mysql命令,mysqldump命令等
python模块:如pymysql
#分两大类:
关系型:如sqllite,db2,oracle,access,sql server,MySQL,注意:sql语句通用
非关系型:mongodb,redis,memcache
#可以简单的理解为:
关系型数据库需要有表结构
非关系型数据库是key-value存储的,没有表结构
一、二进制rpm包安装
- yum -y install mysql-server mysql
二、源码安装
1.解压tar包
- cd /<span style="color: #000000">software
- tar </span>-xzvf mysql-5.6.21-linux-glibc2.5-<span style="color: #000000">x86_64.tar.gz
- mv mysql</span>-5.6.21-linux-glibc2.5-x86_64 mysql-5.6.21
2.添加用户与组
- <span style="color: #000000">groupadd mysql
- useradd </span>-r -<span style="color: #000000">g mysql mysql
- chown </span>-R mysql:mysql mysql-5.6.21
3.安装数据库
- <span style="color: #000000">su mysql
- cd mysql</span>-5.6.21/<span style="color: #000000">scripts
- .</span>/mysql_install_db --user=mysql --basedir=/software/mysql-5.6.21 --datadir=/software/mysql-5.6.21/data
4.配置文件
- cd /software/mysql-5.6.21/support-<span style="color: #000000">files
- cp my</span>-default.cnf /etc/<span style="color: #000000">my.cnf
- cp mysql.server </span>/etc/init.d/<span style="color: #000000">mysql
- vim </span>/etc/init.d/mysql <span style="color: #008000">#</span><span style="color: #008000">若mysql的安装目录是/usr/local/mysql,则可省略此步</span>
- <span style="color: #000000">
- 修改文件中的两个变更值
- basedir</span>=/software/mysql-5.6.21<span style="color: #000000">
- datadir</span>=/software/mysql-5.6.21/<span style="color: #000000">data
- </span>
5.配置环境变量
- vim /etc/<span style="color: #000000">profile
- export MYSQL_HOME</span>=<span style="color: #800000">"</span><span style="color: #800000">/software/mysql-5.6.21</span><span style="color: #800000">"</span><span style="color: #000000">
- export PATH</span>=<span style="color: #800000">"</span><span style="color: #800000">$PATH:$MYSQL_HOME/bin</span><span style="color: #800000">"</span><span style="color: #000000">
- source </span>/etc/profile
6.添加自启动服务
- chkconfig --<span style="color: #000000">add mysql
- chkconfig mysql on</span>
7.启动mysql
- service mysql start
8.登录mysql及改密码与配置远程访问
- mysqladmin -u root password <span style="color: #800000">‘</span><span style="color: #800000">your_password</span><span style="color: #800000">‘</span> <span style="color: #008000">#</span><span style="color: #008000">修改root用户密码</span>
- <span style="color: #000000">
- mysql </span>-u root -p <span style="color: #008000">#</span><span style="color: #008000">登录mysql,需要输入密码</span>
- <span style="color: #000000">
- mysql</span>>GRANT ALL PRIVILEGES ON *.* TO <span style="color: #800000">‘</span><span style="color: #800000">root</span><span style="color: #800000">‘</span>@<span style="color: #800000">‘</span><span style="color: #800000">%</span><span style="color: #800000">‘</span> IDENTIFIED BY <span style="color: #800000">‘</span><span style="color: #800000">your_password</span><span style="color: #800000">‘</span> WITH GRANT OPTION; <span style="color: #008000">#</span><span style="color: #008000">允许root用户远程访问</span>
- <span style="color: #000000">
- mysql</span>>FLUSH PRIVILEGES; <span style="color: #008000">#</span><span style="color: #008000">刷新权限</span>
三、源码安装mariadb
- 1. 解压
- tar zxvf mariadb-5.5.31-linux-<span style="color: #000000">x86_64.tar.gz
- mv mariadb</span>-5.5.31-linux-x86_64 /usr/local/mysql //必需这样,很多脚本或可执行程序都会直接访问这个目录
- 2. 权限
- groupadd mysql //<span style="color: #000000">增加 mysql 属组
- useradd </span>-g mysql mysql //<span style="color: #000000">增加 mysql 用户 并归于mysql 属组
- chown mysql:mysql </span>-Rf /usr/local/mysql //<span style="color: #000000"> 设置 mysql 目录的用户及用户组归属。
- chmod </span>+x -Rf /usr/local/mysql //赐予可执行权限
- 3. 拷贝配置文件
- cp /usr/local/mysql/support-files/my-medium.cnf /etc/my.cnf //复制默认mysql配置 文件到/etc目录
- 4. 初始化
- /usr/local/mysql/scripts/mysql_install_db --user=mysql //<span style="color: #000000">初始化数据库
- cp </span>/usr/local/mysql/support-files/mysql.server /etc/init.d/mysql //<span style="color: #000000">复制mysql服务程序 到系统目录
- chkconfig mysql on </span>//<span style="color: #000000">添加mysql 至系统服务并设置为开机启动
- service mysql start </span>//启动mysql
- 5. 环境变量配置
- vim /etc/profile //<span style="color: #000000">编辑profile,将mysql的可执行路径加入系统PATH
- export PATH</span>=/usr/local/mysql/<span style="color: #000000">bin:$PATH
- source </span>/etc/profile //使PATH生效。
- 6. 账号密码
- mysqladmin -u root password <span style="color: #800000">‘</span><span style="color: #800000">yourpassword</span><span style="color: #800000">‘</span> //<span style="color: #000000">设定root账号及密码
- mysql </span>-u root -p //<span style="color: #000000">使用root用户登录mysql
- use mysql </span>//<span style="color: #000000">切换至mysql数据库。
- select user,host,password </span><span style="color: #0000ff">from</span> user; //<span style="color: #000000">查看系统权限
- drop user </span><span style="color: #800000">‘‘</span>@<span style="color: #800000">‘</span><span style="color: #800000">localhost</span><span style="color: #800000">‘</span>; //<span style="color: #000000">删除不安全的账户
- drop user root@</span><span style="color: #800000">‘</span><span style="color: #800000">::1</span><span style="color: #800000">‘</span><span style="color: #000000">;
- drop user root@</span>127.0.0.1<span style="color: #000000">;
- select user,host,password </span><span style="color: #0000ff">from</span> user; //<span style="color: #000000">再次查看系统权限,确保不安全的账户均被删除。
- flush privileges; </span>//刷新权限
- 7. 一些必要的初始配置
- 1)修改字符集为UTF8
- vi /etc/<span style="color: #000000">my.cnf
- 在[client]下面添加 default</span>-character-set =<span style="color: #000000"> utf8
- 在[mysqld]下面添加 character_set_server </span>= utf8
2)增加错误日志
- vi /etc/<span style="color: #000000">my.cnf
- 在[mysqld]下面添加:
- log</span>-error = /usr/local/mysql/log/<span style="color: #000000">error.log
- general</span>-log-file = /usr/local/mysql/log/<span style="color: #000000">mysql.log
- </span>3<span style="color: #000000">) 设置为不区分大小写,linux下默认会区分大小写。
- vi </span>/etc/<span style="color: #000000">my.cnf
- 在[mysqld]下面添加:
- lower_case_table_name</span>=1
- 修改完重启:
- service mysql restart
安装
#1、下载:MySQL Community Server 5.7.16
http://dev.mysql.com/downloads/mysql/
#2、解压
如果想要让MySQL安装在指定目录,那么就将解压后的文件夹移动到指定目录,如:C:\mysql-5.7.16-winx64
#3、添加环境变量
【右键计算机】--》【属性】--》【高级系统设置】--》【高级】--》【环境变量】--》【在第二个内容框中找到 变量名为Path 的一行,双击】 --> 【将MySQL的bin目录路径追加到变值值中,用 ; 分割】
#4、初始化
- mysqld --initialize-insecure
#5、启动MySQL服务
- mysqld <span style="color: #008000">#</span><span style="color: #008000"> 启动MySQL服务</span>
#6、启动MySQL客户端并连接MySQL服务
- mysql -u root -p <span style="color: #008000">#</span><span style="color: #008000"> 连接MySQL服务器</span>
将MySQL服务制作成windows服务
- 上一步解决了一些问题,但不够彻底,因为在执行【mysqd】启动MySQL服务器时,当前终端会被hang住,那么做一下设置即可解决此问题:
- 注意:--install前,必须用mysql启动命令的绝对路径
- # 制作MySQL的Windows服务,在终端执行此命令:
- <span style="color: #800000">"</span><span style="color: #800000">c:\mysql-5.7.16-winx64\bin\mysqld</span><span style="color: #800000">"</span> --install
- # 移除MySQL的Windows服务,在终端执行此命令:
- <span style="color: #800000">"</span><span style="color: #800000">c:\mysql-5.7.16-winx64\bin\mysqld</span><span style="color: #800000">"</span> --remove
- 注册成服务之后,以后再启动和关闭MySQL服务时,仅需执行如下命令:
- # 启动MySQL服务
- net start mysql
- # 关闭MySQL服务
- net stop mysql
- C:\Users\Administrator> mysqladmin -uroot -p password <span style="color: #800000">"</span><span style="color: #800000">123</span><span style="color: #800000">"</span>
- <span style="color: #000000">net stop MySQL
- mysqld </span>--skip-grant-<span style="color: #000000">tables
- mysql </span>-uroot -<span style="color: #000000">p
- update mysql.user set password</span>=password(<span style="color: #800000">""</span>) where user=<span style="color: #800000">‘</span><span style="color: #800000">root</span><span style="color: #800000">‘</span> <span style="color: #0000ff">and</span> host=<span style="color: #800000">"</span><span style="color: #800000">localhost</span><span style="color: #800000">"</span><span style="color: #000000">;
- flush privileges;
- C:\Users\Administrator</span>>tasklist |<span style="color: #000000">findstr mysql
- mysqld.exe </span>6316 Console 1 454,544<span style="color: #000000"> K
- C:\Users\Administrator</span>>taskkill /F /PID 6316<span style="color: #000000">
- 成功: 已终止 PID 为 </span>6316<span style="color: #000000"> 的进程。
- C:\Users\Administrator</span>><span style="color: #000000">net start MySQL
- MySQL 服务正在启动 .
- MySQL 服务已经启动成功。</span>
#1. 修改配置文件
- <span style="color: #000000">[mysqld]
- default</span>-character-set=<span style="color: #000000">utf8
- [client]
- default</span>-character-set=<span style="color: #000000">utf8
- [mysql]
- default</span>-character-set=<span style="color: #000000">utf8
- </span><span style="color: #008000">#</span><span style="color: #008000">mysql5.5以上:修改方式有所改动</span>
- <span style="color: #000000">
- [mysqld]
- character</span>-set-server=<span style="color: #000000">utf8
- collation</span>-server=<span style="color: #000000">utf8_general_ci
- [client]
- default</span>-character-set=<span style="color: #000000">utf8
- [mysql]
- default</span>-character-set=utf8
#2. 重启服务
#3. 查看修改结果:
- mysql><span style="color: #000000"> \s
- show variables like </span><span style="color: #800000">‘</span><span style="color: #800000">%char%</span><span style="color: #800000">‘</span>
有了mysql这个数据库软件,就可以将程序员从对数据的管理中解脱出来,专注于对程序逻辑的编写
mysql服务端软件即mysqld帮我们管理好文件夹以及文件,前提是作为使用者的我们,需要下载mysql的客户端,或者其他模块来连接到mysqld,然后使用mysql软件规定的语法格式去提交自己命令,实现对文件夹或文件的管理。该语法即sql(Structured Query Language 即结构化查询语言)
SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:
#1、DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER
#2、DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT
#3、DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE
- create database db1 charset utf8;
- <span style="color: #000000">show databases;
- show create database db1;</span>
- alter database db1 charset gbk;
- drop database db1;
- select database();
- use db1;
- create table t1(id int,name char);
- <span style="color: #000000">show tables;
- show create table t1;
- desc t1;</span>
- <span style="color: #000000">alter table t1 add sex char;
- alter table t1 drop sex;
- alter table t1 modify name char(</span>16<span style="color: #000000">);
- alter table t1 change name Name char(</span>13);
- drop table t1;
- <span style="color: #000000">insert into db1.t1 values
- (</span>1,<span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span><span style="color: #000000">),
- (</span>2,<span style="color: #800000">‘</span><span style="color: #800000">alex</span><span style="color: #800000">‘</span><span style="color: #000000">),
- (</span>3,<span style="color: #800000">‘</span><span style="color: #800000">wxx</span><span style="color: #800000">‘</span>);
- select id,name <span style="color: #0000ff">from</span><span style="color: #000000"> db1.t1;
- select </span>* <span style="color: #0000ff">from</span> db1.t1;
- update t1 set name=<span style="color: #800000">‘</span><span style="color: #800000">SB</span><span style="color: #800000">‘</span> where id=2;
- delete <span style="color: #0000ff">from</span> t1 where id=2;
储引擎即表类型,mysql根据不同的表类型会有不同的处理机制
查看引擎
- show engines;
创建引擎
- create table t1(id int)engine=<span style="color: #000000">innodb;
- create table t2(id int)engine</span>=<span style="color: #000000">myisam;
- create table t3(id int)engine</span>=<span style="color: #000000">memory;
- create table t4(id int)engine</span>=blackhole;
- <span style="color: #000000">create table t8(n tinyint);
- insert into t8 values(</span>-1<span style="color: #000000">);
- insert into t8 values(</span>128<span style="color: #000000">);
- insert into t8 values(</span>-129<span style="color: #000000">);
- create table t9(n tinyint unsigned);
- insert into t9 values(</span>-1),(256);
#整型的宽度代表显示宽度
- create table t11(n int(3<span style="color: #000000">) unsigned zerofill);
- create table t12(n int unsigned zerofill);
- create table t13(
- id int
- );
- </span>
- create table t13(x float(255,30<span style="color: #000000">));
- create table t14(x double(</span>255,30<span style="color: #000000">));
- create table t15(x decimal(</span>65,30<span style="color: #000000">));
- insert into t13 values(</span>1.111111111111111111111111111111<span style="color: #000000">);
- insert into t14 values(</span>1.111111111111111111111111111111<span style="color: #000000">);
- insert into t15 values(</span>1.111111111111111111111111111111);
- <span style="color: #000000">create table student(
- id int,
- name char(</span>16<span style="color: #000000">),
- born_year year,
- birth_date date,
- class_time time,
- reg_time datetime
- );
- insert into student values
- (</span>1,<span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span><span style="color: #000000">,now(),now(),now(),now())
- ;
- insert into student values
- (</span>2,<span style="color: #800000">‘</span><span style="color: #800000">alex</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">1999</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">1999-11-11</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">11:11:11</span><span style="color: #800000">‘</span>,<span style="color: #800000">"</span><span style="color: #800000">1999-11-11 11:11:11</span><span style="color: #800000">"</span>)
char:定长
varchar:变长
#宽度代表的是字符的个数
- create table t16(name char(5<span style="color: #000000">));
- create table t17(name varchar(</span>5<span style="color: #000000">));
- insert into t16 values(</span><span style="color: #800000">‘</span><span style="color: #800000">李杰 </span><span style="color: #800000">‘</span>); <span style="color: #008000">#</span><span style="color: #008000">‘李杰 ‘</span>
- <span style="color: #000000">
- insert into t17 values(</span><span style="color: #800000">‘</span><span style="color: #800000">李杰 </span><span style="color: #800000">‘</span>); <span style="color: #008000">#</span><span style="color: #008000">‘李杰 ‘</span>
- <span style="color: #000000">
- select char_length(name) </span><span style="color: #0000ff">from</span> t16; <span style="color: #008000">#</span><span style="color: #008000">5</span>
- <span style="color: #000000">
- select char_length(name) </span><span style="color: #0000ff">from</span> t17; <span style="color: #008000">#</span><span style="color: #008000">3</span>
- <span style="color: #000000">
- mysql</span>> set sql_mode=<span style="color: #800000">‘</span><span style="color: #800000">PAD_CHAR_TO_FULL_LENGTH</span><span style="color: #800000">‘</span><span style="color: #000000">;
- select </span>* <span style="color: #0000ff">from</span> t16 where name=<span style="color: #800000">‘</span><span style="color: #800000">李杰</span><span style="color: #800000">‘</span><span style="color: #000000">;
- select </span>* <span style="color: #0000ff">from</span> t17 where name=<span style="color: #800000">‘</span><span style="color: #800000">李杰</span><span style="color: #800000">‘</span><span style="color: #000000">;
- select </span>* <span style="color: #0000ff">from</span> t16 where name like <span style="color: #800000">‘</span><span style="color: #800000">李杰</span><span style="color: #800000">‘</span><span style="color: #000000">;
- name char(</span>5<span style="color: #000000">)
- egon </span>|alex |wxx |<span style="color: #000000">
- name varchar(</span>5<span style="color: #000000">)
- 1bytes</span>+egon|1bytes+alex|1bytes+wxx|
- <span style="color: #000000">create table employee(
- id int,
- name char(</span>10<span style="color: #000000">),
- sex enum(</span><span style="color: #800000">‘</span><span style="color: #800000">male</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">female</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">other</span><span style="color: #800000">‘</span><span style="color: #000000">),
- hobbies set(</span><span style="color: #800000">‘</span><span style="color: #800000">play</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">eat</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">music</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">read</span><span style="color: #800000">‘</span><span style="color: #000000">)
- );
- insert into employee values
- (</span>1,<span style="color: #800000">‘</span><span style="color: #800000">egon</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">male</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">music,read</span><span style="color: #800000">‘</span><span style="color: #000000">);
- insert into employee values
- (</span>2,<span style="color: #800000">‘</span><span style="color: #800000">alex</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">xxxx</span><span style="color: #800000">‘</span>,<span style="color: #800000">‘</span><span style="color: #800000">music,read</span><span style="color: #800000">‘</span>);
多线程与MySQL(十)
标签:括号 活动 software 用户态 release wait 系统设置 mysqld i/o