浅谈多线程
打上花火
あの日(ひ)见渡(みわた)した渚(なぎさ)を
那天所眺望的海岸
a no hi mi wa ta shi ta na gi sa wo
今(いま)も思(おも)い出(だ)すんだ
直至今日仍能想起
i ma mo o mo i da su n da
砂(すな)の上(うえ)に刻(きざ)んだ言叶(ことば)
在沙滩上刻下的话语
su na no u e ni ki za n da ko to ba
君(きみ)の後(うし)ろ姿(すがた)
和你的背影
ki mi no u shi ro su ga ta
寄(よ)り返(かえ)す波(なみ)が
涌动的波浪
yo ri ka e su na mi ga
足元(あしもと)をよぎり何(なに)かを攫(さら)う
掠过脚边究竟掠走了什么
a shi mo to wo yo gi ri na ni ka wo sa ra u
夕凪(ゆうなぎ)の中(なか)
风平浪静之中
yu u na gi no na ka
日暮(ひぐ)れだけが通(とお)り过(す)ぎてゆく
只有黄昏悄悄地流逝
hi gu re da ke ga to o ri su gi te yu ku
パッと光(ひか)って咲(さ)いた
光芒砰然绽放
pa tto hi ka tte sa i ta
花火(はなび)を见(み)てぃた
烟花映入眼帘
ha na bi wo mi te i ta
きっとまだ终(お)わらない夏(なつ)が
一定是夏天还未结束
ki tto ma da o wa ra na i na tsu ga
暧昧(あいまい)な心(こころ)を解(と)かして繋(つな)いだ
将暧昧的心结解开再紧紧相连
a i ma i na ko ko ro wo to ka shi te tsu na i da
この夜(よる)が続(つづ)いて欲(ほ)しかった
愿今夜永不结束
ko no yo ru ga tsu zu i te ho shi ka tta
「あと何度(なんど)君(きみ)と同(おな)じ花火(はなび)を见(み)られるかな」って
还能与你一起看几次同样的烟花呢
a to na n do ki mi to o na ji ha na bi wo mi ra re ru ka na tte
笑(わら)う颜(かお)に何(なに)ができるだろうか
面对你的笑容 我又能做些什么呢
wa r au ka o ni na ni ga de ki ru da rou ka
伤(きず)つくこと 喜(よろこ)ぶこと
受伤亦或是喜悦
ki zu tsu ku ko to yo ro ko bu ko to
缲(く)り返(かえ)す波(なみ)と情动(じょうどう)
浪来浪去与情动
ku ri ka e su na mi to jyou dou
焦燥(しょうそう)最终列车(さいしゅうれっしゃ)の音(おと)
焦躁响起了末班列车的声音
sho u sou sai shu u re ssha no o to
何度(なんど)でも言叶(ことば)にして君(きみ)を呼(よ)ぶよ
无数次用言语呼唤着你
na n do de mo ko to ba ni shi te ki mi wo yo bu yo
波间(なみま)を选(えら)びもう一度(いちど)...
向着海浪 再一次…
na mi ma wo e ra bi mo u i chi do do do do do
もう二度(にど)と悲(かな)しまずに済(す)むように
祈祷不再感受那份悲伤
mo u ni do to ka na shi ma zu ni su mu yo u ni
はっと息(いき)を饮(の)めば
如果突然屏住呼吸
ha tto i ki wo no me ba
消(き)えちゃいそうな光(ひかり)が
那么即将消逝的光芒
ki e cha i sou na hi ka ri ga
きっとまだ 胸(むね)に住(す)んでいた
一定仍能够留存心中
ki tto ma da mune ni su n de i ta
手(て)を伸(の)ばせば触(ふ)れた
伸出手就能触及
te wo no ba se ba hu re ta
暖(あった)かい未来(みらい)は
那温暖的未来
a tta ka i mi ra i wa
密(ひそ)かに二人(ふたり)を见(み)ていた
默默地守望着两人
hi so ka ni hu ta ri wo mi te i ta
パッと花火(はなび)が「パッと花火(はなび)が」
怦然绽放的烟花(怦然绽放的烟花)
pa tto ha na bi ga「pa tto ha na bi ga」
夜(よる)に咲(さ)いた「夜(よる)に咲(さ)いた」
在夜空中绽放(在夜空中绽放)
yo ru ni sa i ta「yo ru ni sa i ta」
夜(よる)に咲(さ)いて「夜(よる)に咲(さ)いて」
在夜空中绽放后(在夜空中绽放后)
yo ru ni sai te「yo ru ni sa i te」
静(しず)かに消(き)えた「静(しず)かに消(き)えた」
又静静地消失(又静静地消失)
shi zu ka ni ki e ta「shi zu ka ni ki e ta」
离(はな)さないで 「离(はな)れないで」
请不要离开(请不要离开)
ha na sa na i de「ha na re na i de」
もう少(すこ)しだけ「もう少(すこ)しだけ」
再给一点点时间(再给一点点时间)
mo u su ko shi da ke「mo u su ko shi da ke」
もう少(すこ)しだけ
再给一点点时间
mo u su ko shi da ke
このままで
就一直这样
ko no ma ma de
あの日(ひ)见渡(みわた)した渚(なぎさ)を
那天所眺望的海岸
a no hi mi wa ta shi ta na gi sa wo
今(いま)も思(おも)い出(だ)すんだ
直至今日仍能想起
i ma mo o mo i da su n da
砂(すな)の上(うえ)に刻(きざ)んだ言叶(ことば)
在沙滩上刻下的话语
su na no u e ni ki za n da ko to ba
君(きみ)の後(うし)ろ姿(すがた)
和你的背影
ki mi no u shi ro su ga ta
パッと光(ひか)って咲(さ)いた
光芒怦然绽放
pa tto hi ka tte sai ta
花火(はなび)を见(み)ていた
烟花映入眼帘
ha na bi wo mi te i ta
きっとまだ终(お)わらない夏(なつ)が
还未结束的夏天 一定会将
ki tto ma da o wa ra na i na tsu ga
暧昧(あいまい)な心(こころ)を解(と)かして繋(つな)いだ
暧昧的心结融化相连在一起
a i ma i na ko ko ro wo to ka shi te tsu na i da
この夜(よる)が続(つづ)いて欲(ほ)しかった
愿今夜永不结束[2]
ko no yo ru ga tsu zu i te ho shi ka tta
考虑到一般在 OI 上没啥用,所以真的非常浅……
对于不太好用的 pthread_create
thread
就先按下不表,直接说最有用的 async
。
async(T,F,a,b,...)
是函数,返回值是 future
,可以用 .get()
获得其返回值,.wait()
等待到函数进行完,.wait_for(t)
,在 t
秒内等待,超时则返回。
参数中 F
表示要调用的函数,a,b,...
是其参数,其参数只能传值,想传引用的话要用 ref(a)
和 cref(a)
,其中 a
是参数,ref
是引用,cref
是常量引用。
T
是创建策略,一共有三种:launch::async
表示立刻调用函数; launch::deferred
表示在查询值(调用 .get()
等)时调用函数; launch::async|launch::deferred
是默认策略,按照编译器指定,一般是 launch::async
async
封装的很好,我们不需要考虑其是否会在主线程结束前结束,也不需要自己结束和释放,其会在返回值析构时调用 .wait()
。
对于多个线程同时操作同一部分,有 mutex
和 atomic
。
mutex
是一个类,对于其对象,有 .lock
:表示上锁,其他线程在上锁的地方会阻塞,直到解锁,.unlock
:表示解锁,.try_lock()
是尝试上锁,若已经上锁返回 false
,否则上锁并返回 true
。
注意若其被同一个线程锁住,会死锁。
atomic<T>
专注于变量,其中 T
是变量类型,其与正常的变量大体没区别,只是在多线程时避免同时操作,速度快于频繁上锁。
基本上语法就是这么些,更深的可以自己搜。其实对于简单实现一个对拍之类的,只要会 async
基本就够了。
一个简单的多线程对拍
应该是比较易懂的。
T
是线程数,N
是每线程测试组数。
首先要建一个叫 data 的文件夹。
程序叫 1.cpp;std 叫 std.cpp;数据叫 rnd.cpp
编译时加 -pthread
或 -lpthread
。
有没有好心人帮忙测一下效率 QwQ
#include<bits/stdc++.h>
using namespace std;
int S(const string &a){return system(a.c_str());}
const int T=30,N=100;
future<void> pt[T];void Run(int id){string p=" data/"+to_string(id),i=p+".in ",o=p+".out ",a=p+".ans ";for(int p=1;p<=N;++p) if(S("./rnd >"+i+"&& ./std <"+i+'>'+a+"&& ./1<"+i+'>'+o+"&& diff"+o+a+"-Z > /dev/null")) return cout<<"Wa\n",void();S("rm -f"+i+";rm -f"+o+";rm -f"+a);
}
int main(){assert(!S("g++ 1.cpp -o 1 -O2 -std=c++14 && g++ rnd.cpp -o rnd -O2 -std=c++14 && g++ std.cpp -o std -O2 -std=c++14"));S("cd data && rm -rf *"); for(int i=0;i<T;++i) pt[i]=async(Run,i);
}
P