版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開(kāi)發(fā)技術(shù)】C++中Boost多線(xiàn)程、線(xiàn)程同步的示例分析
在下給大家分享一下C++中Boost多線(xiàn)程、線(xiàn)程同步的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!線(xiàn)程的創(chuàng)建
boost_thread,boost_system
多線(xiàn)程的創(chuàng)建
線(xiàn)程的參數(shù)傳遞
線(xiàn)程的創(chuàng)建方式
線(xiàn)程的join
加入join,回收線(xiàn)程
線(xiàn)程中斷
線(xiàn)程中斷2,
線(xiàn)程組
boost
線(xiàn)程的死鎖
boost
線(xiàn)程遞歸鎖
線(xiàn)程互斥鎖,線(xiàn)程同步
unique_lock
鎖,離開(kāi)作用域自動(dòng)釋放
unique_lock
鎖
示例
2,可以顯式的釋放鎖
boost
1次初始化
boost
條件變量
boost
線(xiàn)程鎖,一個(gè)賬戶(hù)往另外一個(gè)賬戶(hù)轉(zhuǎn)錢(qián)案例
boost
upgrade_lock知識(shí)背景:理解什么是線(xiàn)程,什么是進(jìn)程,區(qū)別是什么,如何使用多進(jìn)程多線(xiàn)程線(xiàn)程的創(chuàng)建boost_thread,boost_systemchunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun()
{
cout
<<
"Hello
Boost
threads
!"
<<
endl;
}
int
main()
{
boost::thread
t1(fun);
t1.join();
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
Hello
Boost
threads
!
chunli@Linux:~/boost$多線(xiàn)程的創(chuàng)建chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun1(){cout
<<
"Hello
Boost
threads
1!"
<<
endl;}
void
fun2(){cout
<<
"Hello
Boost
threads
2!"
<<
endl;}
void
fun3(){cout
<<
"Hello
Boost
threads
3!"
<<
endl;}
int
main()
{
boost::thread
t1(fun1); t1.join();
boost::thread
t2(fun2); t2.join();
boost::thread
t3(fun3); t3.join();
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
Hello
Boost
threads
1!
Hello
Boost
threads
2!
Hello
Boost
threads
3!
chunli@Linux:~/boost$線(xiàn)程的參數(shù)傳遞chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun1(const
int
&id){cout
<<
"threads
id
"<<id
<<
endl;}
void
fun2(const
int
&id){cout
<<
"threads
id
"<<id
<<
endl;}
void
fun3(const
int
&id){cout
<<
"threads
id
"<<id
<<
endl;}
int
main()
{
boost::thread
t1(fun1,1); t1.join();
boost::thread
t2(fun2,2); t2.join();
boost::thread
t3(fun3,3); t3.join();
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
threads
id
2
threads
id
3
chunli@Linux:~/boost$線(xiàn)程的創(chuàng)建方式chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun1(const
int
&id)
{
cout
<<
"threads
id
"<<id
<<
endl;
}
struct
MyThread
{
void
operator()(const
int
&id)
{
cout
<<
"threads
id
"<<id
<<
endl;
}
void
fun(const
int
&id)
{
cout
<<
"threads
id
"<<id
<<
endl;
}
};
int
main()
{
boost::thread
t1(fun1,1);//自由函數(shù)
t1.join();
MyThread
mythread;
boost::thread
t2(mythread,2);//函數(shù)對(duì)象
t2.join();
boost::thread
t3(&MyThread::fun,mythread,3);
//成員函數(shù)
t3.join();
boost::thread
t4(MyThread(),4); //臨時(shí)對(duì)象
t4.join();
boost::thread
t5(boost::ref(mythread),5);//對(duì)象引用
t5.join();
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
threads
id
2
threads
id
3
threads
id
4
threads
id
5
chunli@Linux:~/boost$線(xiàn)程的joinchunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun1(const
int
&id){cout
<<
"threads
id
"<<id
<<
endl;}
int
main()
{
boost::thread
t1(fun1,1);
//t1.join();
cout
<<
"main
end!"
<<
endl;
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!threads
id
1
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!
threads
id
1
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!
threads
id
1chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!
threads
id
1
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
main
end!
threads
id
1
chunli@Linux:~/boost$
可以看出,如果沒(méi)有join的等待,結(jié)果是不可預(yù)期的.加入join,回收線(xiàn)程chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
void
fun1(const
int
&id){cout
<<
"threads
id
"<<id
<<
endl;}
int
main()
{
boost::thread
t1(fun1,1);
t1.join();
cout
<<
"main
end!"
<<
endl;
return
0;
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
main
end!
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
main
end!
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
main
end!
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
threads
id
1
main
end!
chunli@Linux:~/boost$線(xiàn)程中斷chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
void
f1(const
int&
id)
{
cout
<<
"thread
#"
<<
id
<<
":
started"
<<
endl;
boost::system_time
const
timeout
=
boost::get_system_time()+
boost::posix_time::seconds(3);
thread::sleep(timeout);//sleep不會(huì)放棄時(shí)間片
cout
<<
"thread
#"
<<
id
<<
":
ended"
<<
endl;
}
void
f2(const
int&
id)
{
cout
<<
"thread
#"
<<
id
<<
":
started"
<<
endl;
thread::yield();//預(yù)定義中斷點(diǎn).主動(dòng)放棄時(shí)間片
cout
<<
"thread
#"
<<
id
<<
":
ended"
<<
endl;
}
void
f3(const
int&
id)
{
cout
<<
"thread
#"
<<
id
<<
":
started"
<<
endl;
boost::this_thread::interruption_point();//預(yù)定義中斷點(diǎn)
cout
<<
"thread
#"
<<
id
<<
":
ended"
<<
endl;
}
int
main()
{
thread
t1(f1,
1); errupt();
thread
t2(f2,
2);
thread
t3(f3,
3); errupt();
t1.join();
t2.join();
t3.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
thread
#2:
started
thread
#1:
started
thread
#3:
started
thread
#2:
ended
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
thread
#1:
started
thread
#3:
started
thread
#2:
started
thread
#2:
ended
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
thread
#thread
#2:
started1:
started
thread
#3:
started
thread
#2:
ended
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
thread
#3:
started
thread
#1:
started
thread
#2:
started
thread
#2:
ended
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
thread
#2:
started
thread
#3:
started
thread
#thread
#2:
ended
1:
started
chunli@Linux:~/boost$
只有2線(xiàn)程不會(huì)被打斷線(xiàn)程中斷2,chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
void
print(const
int&
id)
{
boost::this_thread::disable_interruption
di;//創(chuàng)建一個(gè)不可被打斷的對(duì)象
cout
<<
boost::this_thread::interruption_enabled()
<<
endl;
cout
<<
"thread
#"
<<
id
<<
":
";
//boost::this_thread::sleep(boost::posix_time::seconds(2));
boost::system_time
const
timeout
=
boost::get_system_time()
+
boost::posix_time::seconds(2);
thread::sleep(timeout);
for
(int
i
=
1;
i
<
11;
++i)
{
cout
<<
i
<<
'
';
}
cout
<<
endl;
boost::this_thread::restore_interruption
ri(di);//到這里,對(duì)象不可被打斷
cout
<<
boost::this_thread::interruption_enabled()
<<
endl;
//實(shí)際上,是可以被打斷
}
int
main()
{
//線(xiàn)程還沒(méi)有運(yùn)行結(jié)束,叫被打斷
thread
t1(print,
1);
thread
t2(print,
2);
thread
t3(print,
3); errupt();
t1.join();
t2.join();
t3.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
0
thread
#1:
0
thread
#3:
0
thread
#2:
1
2
3
4
5
6
7
8
9
10
1
1
2
3
4
5
6
7
8
9
10
1
1
2
3
4
5
6
7
8
9
10
1
chunli@Linux:~/boost$
g++
main.cpp
-l
boost_thread
-l
boost_system
&&
./a.out
0
thread
#1:
0
thread
#2:
0
thread
#3:
1
2
3
4
5
6
7
8
9
10
1
1
2
3
4
5
6
7
8
9
10
1
1
2
3
4
5
6
7
8
9
10
1
chunli@Linux:~/boost$線(xiàn)程組chunli@Linux:~/桌面/qt_pro/01/untitled$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
void
f1(){
cout
<<
"fun1
"
<<
endl;}
void
f2(){
cout
<<
"fun2
"
<<
endl;}
int
main()
{
boost::thread_group
group;
for(int
i
=
0;i<3;++i)
{
group.create_thread(f1);
}
group.add_thread(new
boost::thread(f2));
cout<<group.size()<<endl;
group.join_all();
}
chunli@Linux:~/桌面/qt_pro/01/untitled$
g++
main.cpp
-lboost_thread
-lboost_system
-Wall
&&
./a.out
fun1
4
fun1
fun2
fun1
chunli@Linux:~/桌面/qt_pro/01/untitled$
g++
main.cpp
-lboost_thread
-lboost_system
-Wall
&&
./a.out
fun1
fun1
fun1
4
fun2
chunli@Linux:~/桌面/qt_pro/01/untitled$boost線(xiàn)程的死鎖chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::mutex
m;
void
function1()
{
m.lock();
cout
<<
"function
1
\n";
m.unlock();
}
void
function2()
{
m.lock();
cout
<<
"function
2
\n";
function1();
m.unlock();
}
int
main()
{
thread
t1(function1);
t1.join();
thread
t2(function2);
t2.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system&&
./a.out
function
1
function
2
^C
chunli@Linux:~/boost$boost線(xiàn)程遞歸鎖chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::recursive_mutex
m;
void
function1()
{
m.lock();
cout
<<
"function
1
\n";
m.unlock();
}
void
function2()
{
m.lock();
cout
<<
"function
2
\n";
function1();
m.unlock();
}
int
main()
{
thread
t1(function1);
t1.join();
thread
t2(function2);
t2.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
-lpthread
&&
./a.out
function
1
function
2
function
1
chunli@Linux:~/boost$線(xiàn)程互斥鎖,線(xiàn)程同步boost::mutex
m;
void
function1(int
id)
{
m.lock();
cout
<<"thread
#"<<id<<":";
for(int
i=0;i<15;i++)
cout
<<
i<<'
';
cout
<<
endl;
m.unlock();
}
int
main()
{
thread
t1(function1,1);
t1.join();
thread
t2(function1,2);
t2.join();
thread
t3(function1,3);
t3.join();
thread
t4(function1,4);
t4.join();
thread
t5(function1,5);
t5.join();
thread
t6(function1,6);
t6.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
-lpthread
&&
./a.out
thread
#1:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread
#2:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread
#3:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread
#4:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread
#5:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
thread
#6:0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
chunli@Linux:~/boost$unique_lock鎖,離開(kāi)作用域自動(dòng)釋放chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<list>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::mutex
m;
int
k
=
0;
void
decrement()
{
boost::unique_lock<boost::mutex>
lock(m);
for(int
i
=
0;i<=100;++i)
{
k-=i;
}
cout
<<
"after
decrement
k="<<k
<<
endl;
}
void
increment()
{
boost::unique_lock<boost::mutex>
lock(m);
for(int
i
=
0;i<=100;++i)
{
k+=i;
}
cout
<<
"after
increment
k="<<k
<<
endl;
}
int
main()
{
boost::thread
t1(increment);
t1.join();
boost::thread
t2(decrement);
t2.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
-lpthread
&&
./a.out
after
increment
k=5050
after
decrement
k=0
chunli@Linux:~/boost$unique_lock鎖示例2,可以顯式的釋放鎖chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<vector>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::mutex
m;
void
updateString()
{
boost::unique_lock<boost::mutex>
lock(m);//lock
lock.unlock();//unlock
lock.lock();
}
int
main()
{
thread
t1(updateString);
t1.join();
thread
t2(updateString);
t2.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
-lpthread
&&
./a.out
chunli@Linux:~/boost$boost1次初始化chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::once_flag
once
=
BOOST_ONCE_INIT;
//
注意這個(gè)操作不要遺漏了
void
func()
{
cout
<<
"Will
be
called
but
one
time!"
<<
endl;
}
void
threadFunc()
{
//
func();
boost::call_once(&func,
once);
}
int
main()
{
boost::thread_group
threads;
for
(int
i
=
0;
i
<
5;
++i)
threads.create_thread(&threadFunc);
threads.join_all();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
&&
./a.out
Will
be
called
but
one
time!
chunli@Linux:~/boost$boost條件變量chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
boost::condition_variable
cond;
//
關(guān)聯(lián)多個(gè)線(xiàn)程的條件變量
boost::mutex
m;
//
保護(hù)共享資源
k
的互斥體
int
k
=
0;
//
共享資源
void
f1(const
int&
id)
{
boost::unique_lock<boost::mutex>
lock(m);
while
(k
<
5)
{
cout
<<
"thread
#"
<<
id
<<
":
k
<
5,
waiting
..."
<<
endl;
cond.wait(lock);
//
#1
}
cout
<<
"thread
#"
<<
id
<<
":
now
k
>=
5,
printing
..."
<<
endl;
}
void
f2(const
int&
id)
{
boost::unique_lock<boost::mutex>
lock(m);
cout
<<
"thread
#"
<<
id
<<
":
k
will
be
changed
..."
<<
endl;
k
+=
5;
cond.notify_all();
//
#2
不需lock
}
int
main()
{
//
如果f2()中是
cond.notify_one(),結(jié)果?
boost::thread
t1(f1,
1);
boost::thread
t2(f1,
2);
boost::thread
t3(f2,
100);
t1.join();
t2.join();
t3.join();
}
chunli@Linux:~/boost$
g++
main.cpp
-lboost_thread
-lboost_system
&&
./a.out
thread
#1:
k
<
5,
waiting
...
thread
#2:
k
<
5,
waiting
...
thread
#100:
k
will
be
changed
...
thread
#1:
now
k
>=
5,
printing
...
thread
#2:
now
k
>=
5,
printing
...
chunli@Linux:~/boost$boost線(xiàn)程鎖,一個(gè)賬戶(hù)往另外一個(gè)賬戶(hù)轉(zhuǎn)錢(qián)案例chunli@Linux:~/boost$
cat
main.cpp
#include
<iostream>
#include
<boost/thread.hpp>
using
namespace
std;
using
boost::thread;
class
Account
{
boost::mutex
m;
double
balance;
public:
Account()
:
balance()
{
}
Account(const
double&
bal)
:
balance(bal)
{
}
double
getBalance()
const
{
return
balance;
}
friend
void
transfer(Account&
from,
Account&
to,
double
amount);
};
////
version
3:
OK
(使用lock()
和
unique_lock)
//void
transfer(Account&
from,
Account&
to,
double
amount)
{
//
boost::lock(from.m,
to.m);
//
boost::unique_lock<boost::mutex>
lockFrom(from.m,
boost::adopt_lock);
//
boost::unique_lock<boost::mutex>
lockTo(to.m,
boost::adopt_lock);
//
//
from.balance
-=
amount;
//
to.balance
+=
amount;
//}
//
version
2:
OK
(使用lock()
和
lock_guard)
void
transfer(Account&
from,
Account&
to,
double
amount)
{
boost::lock(from.m,
to.m);
boost::lock_guard<boost::mutex>
lockFrom(from.m,
boost::adopt_lock);
boost::this_thread::sleep(boost::posix_time::seconds(1));
boost::lock_guard<boost::mutex>
lockTo(to.m,
boost::adopt_lock);
from.balance
-=
amount;
to.balance
+=
am
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 《基于物聯(lián)網(wǎng)的農(nóng)業(yè)烤煙環(huán)境監(jiān)控系統(tǒng)》
- 《水力劈裂作用下混凝土雙K斷裂研究及數(shù)值模擬》
- 《旋轉(zhuǎn)沖壓轉(zhuǎn)子系統(tǒng)流激振動(dòng)研究》
- 2025年度網(wǎng)約車(chē)平臺(tái)與司機(jī)合作合同范本3篇
- 2024版檢驗(yàn)責(zé)任委托合同 fChain版B版
- 小學(xué)數(shù)學(xué)與科學(xué)在商業(yè)分析中的融合實(shí)踐
- 生態(tài)恢復(fù)治理工程施工方案
- 蕪湖2025年安徽蕪湖鳩江區(qū)選聘“警民聯(lián)調(diào)”室專(zhuān)職人民調(diào)解員16人筆試歷年典型考點(diǎn)(頻考版試卷)附帶答案詳解版
- 2025年中國(guó)生化球行業(yè)市場(chǎng)發(fā)展前景及發(fā)展趨勢(shì)與投資戰(zhàn)略研究報(bào)告
- 中國(guó)水產(chǎn)飼料行業(yè)市場(chǎng)深度調(diào)研及發(fā)展策略建議研究報(bào)告(2024-2030版)
- 工程量確認(rèn)單范本
- 潔凈室工程行業(yè)深度分析
- 頻譜儀N9020A常用功能使用指南
- 天津高考英語(yǔ)詞匯3500
- 醫(yī)療質(zhì)量檢查分析及整改措施反饋
- psa制氮機(jī)應(yīng)急預(yù)案
- 三年級(jí)下冊(cè)數(shù)學(xué)教案-6練習(xí)五-北師大版
- 六年級(jí)作文指導(dǎo)暑假趣事經(jīng)典課件
- 最敬業(yè)員工無(wú)記名投票選舉表
- 建設(shè)工程質(zhì)量檢測(cè)作業(yè)指導(dǎo)書(shū)+儀器設(shè)備操作規(guī)程2021版
- 土方測(cè)量報(bào)告
評(píng)論
0/150
提交評(píng)論