本文整理汇总了C++中scheduler函数的典型用法代码示例。如果您正苦于以下问题:C++ scheduler函数的具体用法?C++ scheduler怎么用?C++ scheduler使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了scheduler函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: TEST_F
TEST_F(TransactionTests, AbortTest) {
for (auto test_type : TEST_TYPES) {
concurrency::TransactionManagerFactory::Configure(test_type);
auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
std::unique_ptr<storage::DataTable> table(
TransactionTestsUtil::CreateTable());
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Update(0, 100);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(0);
scheduler.Txn(1).Commit();
scheduler.Run();
EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
//printf("==========result=%d\n", int(scheduler.schedules[1].results[0]));
EXPECT_EQ(0, scheduler.schedules[1].results[0]);
}
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Insert(100, 0);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(100);
scheduler.Txn(1).Commit();
scheduler.Run();
EXPECT_EQ(RESULT_ABORTED, scheduler.schedules[0].txn_result);
EXPECT_EQ(RESULT_SUCCESS, scheduler.schedules[1].txn_result);
EXPECT_EQ(-1, scheduler.schedules[1].results[0]);
}
}
}
开发者ID:seckcoder,项目名称:peloton,代码行数:35,代码来源:transaction_test.cpp
示例2: TEST_F
TEST_F(MVCCTest, AbortVersionChainTest) {
LOG_INFO("AbortVersionChainTest");
for (auto protocol : TEST_TYPES) {
concurrency::TransactionManagerFactory::Configure(
protocol, ISOLATION_LEVEL_TYPE_FULL);
auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
std::unique_ptr<storage::DataTable> table(
TransactionTestsUtil::CreateTable());
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Update(0, 100);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(0);
scheduler.Txn(1).Commit();
scheduler.Run();
ValidateMVCC_OldToNew(table.get());
}
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Insert(100, 0);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(100);
scheduler.Txn(1).Commit();
scheduler.Run();
ValidateMVCC_OldToNew(table.get());
}
}
}
开发者ID:GeorgeErickson,项目名称:peloton,代码行数:35,代码来源:mvcc_test.cpp
示例3: tlb_handler
/**********************************************************************
TLB_HANDLER
Caricato all'arrivo di una eccezione di tipo TLBTRAP.
Affida il controllo del thread corrente ad un Trap Manager, se
specificato, altrimenti viene terminato tutto il sottoalbero
corrispondente.
**********************************************************************/
void tlb_handler(){
tcb_t *manager;
/* TUTTE le operazioni sono equivalenti a quelle per SYSBP */
current_thread->cpu_slice += (GET_TODLOW - current_thread_tod);
current_thread->cpu_time += (GET_TODLOW - current_thread_tod);
save_state(tlbtrap_oldarea, &(current_thread->t_state));
manager = current_thread->tlbtrap_manager_thread;
if (manager == NULL) {
terminate(current_thread);
current_thread = NULL;
scheduler();
}
else {
send(current_thread, manager, tlbtrap_oldarea->cause);
current_thread->waiting_for = manager;
insertThread(&wait_queue, current_thread);
current_thread = NULL;
scheduler();
}
}
开发者ID:alainrk,项目名称:AmiKaya11,代码行数:43,代码来源:exceptions.c
示例4: TEST_F
TEST_F(SerializableTransactionTests, AbortTest) {
for (auto protocol_type : PROTOCOL_TYPES) {
concurrency::TransactionManagerFactory::Configure(protocol_type);
auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
storage::DataTable *table = TestingTransactionUtil::CreateTable();
{
TransactionScheduler scheduler(2, table, &txn_manager);
scheduler.Txn(0).Update(0, 100);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(0);
scheduler.Txn(1).Commit();
scheduler.Run();
EXPECT_EQ(ResultType::ABORTED, scheduler.schedules[0].txn_result);
EXPECT_EQ(ResultType::SUCCESS, scheduler.schedules[1].txn_result);
EXPECT_EQ(0, scheduler.schedules[1].results[0]);
}
{
TransactionScheduler scheduler(2, table, &txn_manager);
scheduler.Txn(0).Insert(100, 0);
scheduler.Txn(0).Abort();
scheduler.Txn(1).Read(100);
scheduler.Txn(1).Commit();
scheduler.Run();
EXPECT_EQ(ResultType::ABORTED, scheduler.schedules[0].txn_result);
EXPECT_EQ(ResultType::SUCCESS, scheduler.schedules[1].txn_result);
EXPECT_EQ(-1, scheduler.schedules[1].results[0]);
}
}
}
开发者ID:wy4515,项目名称:peloton,代码行数:33,代码来源:serializable_transaction_test.cpp
示例5: DirtyReadTest
void DirtyReadTest() {
auto &txn_manager = concurrency::TransactionManagerFactory::GetInstance();
std::unique_ptr<storage::DataTable> table(
TransactionTestsUtil::CreateTable());
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
// T1 updates (0, ?) to (0, 1)
// T2 reads (0, ?)
// T1 commit
// T2 commit
scheduler.Txn(0).Update(0, 1);
scheduler.Txn(1).Read(0);
scheduler.Txn(0).Commit();
scheduler.Txn(1).Commit();
scheduler.Run();
if (RESULT_SUCCESS == scheduler.schedules[0].txn_result &&
RESULT_SUCCESS == scheduler.schedules[1].txn_result) {
// Don't read uncommited value
EXPECT_EQ(0, scheduler.schedules[1].results[0]);
}
}
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Update(1, 1);
scheduler.Txn(1).Read(1);
scheduler.Txn(1).Commit();
scheduler.Txn(0).Commit();
scheduler.Run();
if (RESULT_SUCCESS == scheduler.schedules[0].txn_result &&
RESULT_SUCCESS == scheduler.schedules[1].txn_result) {
// Don't read uncommited value
EXPECT_EQ(0, scheduler.schedules[1].results[0]);
}
}
{
TransactionScheduler scheduler(2, table.get(), &txn_manager);
scheduler.Txn(0).Delete(2);
scheduler.Txn(1).Read(2);
scheduler.Txn(0).Commit();
scheduler.Txn(1).Commit();
scheduler.Run();
if (RESULT_SUCCESS == scheduler.schedules[0].txn_result &&
RESULT_SUCCESS == scheduler.schedules[1].txn_result) {
// Don't read uncommited value
EXPECT_EQ(0, scheduler.schedules[1].results[0]);
}
}
}
开发者ID:eric-haibin-lin,项目名称:peloton-1,代码行数:60,代码来源:isolation_level_test.cpp
示例6: timer
/* Nota, hay que mandarle el EOI al PIC porque scheduler() NO vuelve,
* Si no le mandamos el EOI nosotros no se lo manda nadie.
* Además, hay que mandarle el EOI antes de hacer el cambio de contexto,
* si lo hacemos después lo vamos a estar haciendo dos veces.
* Una vez cuando nos vuelve a tocar la ejecución y volvemos de scheduler()
* y la otra cuando volvemos al despachador de interrupciones.
*/
int timer( struct registers *r ) {
#define TIEMPO_ACTUALIZCION 10 //Totalmente arbitrario
if (tarea_activa == -1) {
pic8259A_send_EOI( r->nro );
scheduler();
}
//Referente a la actualizacion de pantalla activa
/*++contador_actualizar_pantalla;
if(contador_actualizar_pantalla > TIEMPO_ACTUALIZCION) {
contador_actualizar_pantalla = 0;
if( tarea_en_pantalla != -1 )mostrar_slot(tarea_en_pantalla+1);
}*/
//Referente a la decrementacion de quantum de tarea_activa
//Decrementamos quantum
--tareas[tarea_activa].quantum_actual;
//si termino, reestablecemos y cambiamos a la proxima llamando a scheduler
if (tareas[tarea_activa].quantum_actual<=0) {
//Restablecemos quantums gastado
tareas[tarea_activa].quantum_actual = tareas[tarea_activa].quantum_fijo;
//Llamamos al scheduler para que elija proxima tarea
pic8259A_send_EOI( r->nro );
scheduler();
}
return 0;
}
开发者ID:engrnasirkhan,项目名称:orga2kernel,代码行数:37,代码来源:kernel.c
示例7: interruptHandler
void
interruptHandler(IntType which)
{
switch (which) {
case TimerInt:
DEBUG('e', "TimerInt interruput\n");
if(current!=NULL){
//printf("reinserting pid %d\n",current->pid);
l_insert(readyq,current);
}
else{
//printf("current is NULL at timer interrupt\n");
}
scheduler();
break;
case ConsoleReadInt:
DEBUG('e', "ConsoleReadInt interrupt\n");
if(consolewait !=NULL){
V_kt_sem(consolewait);
}
if(current!=NULL){
l_insert(readyq,current);
}
scheduler();
break;
case ConsoleWriteInt:
DEBUG('e', "ConsoleWriteInt interrupt\n");
if(writeok!=NULL){
//printf("increment writeok\n");
V_kt_sem(writeok);
}
/*
if(current!=NULL){
printf("reinserting pid %d\n",p->pid);
l_insert(readyq,*p);
}
*/
else{
//printf("this shouldn't happen\n");
}
scheduler();
break;
default:
DEBUG('e', "Unknown interrupt\n");
scheduler();
break;
}
}
开发者ID:Naturalclar,项目名称:Project4,代码行数:53,代码来源:exception.c
示例8: NosuchDebug
void
Region::UpdateSound() {
std::string sound = params.sound;
std::map<std::string,Sound>::iterator it = Sounds.find(sound);
if ( it == Sounds.end() ) {
NosuchDebug("Hey, Updatesound found invalid sound, region=%d sound=%s",id,sound.c_str());
return;
}
NosuchDebug(1,"Region::UpdateSound region=%d sound=%s",
id,params.sound.c_str());
int ch = palette->findSoundChannel(sound,id);
if ( ch < 0 ) {
NosuchDebug("Region::UpdateSound Unable to find channel for sound=%s, using existing channel 1",sound.c_str());
ch = 1;
}
if ( ch != _channel ) {
NosuchDebug(1,"Existing channel for region %d is %d, new channel needs to be %d",
id,_channel,ch);
// Tempting to send ANO for the old channel, but the whole point
// of the dynamic channel stuff is to avoid the need to cut off
// old sounds when changing to new ones.
_channel = ch;
// Send ANO on the new channel, to terminate
// anything currently playing there.
scheduler()->ANO(_channel);
} else {
NosuchDebug(1,"Existing channel for region %d is %d",id,_channel);
}
MidiProgramChange* msg = Sound::ProgramChangeMsg(_channel,sound);
if ( msg == NULL ) {
NosuchDebug("HEY!! ProgramChangeMsg returned null for sound=%s",sound.c_str());
return;
}
NosuchDebug("CHANGE rgn=%d sound=%s ch=%d",
id,sound.c_str(),ch);
NosuchDebug(1," progchange=%s", msg->DebugString().c_str());
int loopid;
if ( _loop == NULL )
loopid = -1;
else
loopid = _loop->id();
scheduler()->SendMidiMsg(msg,loopid);
Sleep(150); // Lame attempt to avoid Alchemy bug when it gets lots of Program Change messages
}
开发者ID:phonexhsu,项目名称:VizBench,代码行数:48,代码来源:Region.cpp
示例9: useExStVec
void useExStVec(int type){
if(currentProcess!=NULL) {
/* Se ho già fatto spectrapvec per il tipo di eccezione*/
if (currentProcess->excStVec[type*2]!=NULL){
/* Salvo lo stato nella oldarea adeguata*/
switch(type){
case SPECTLB:
saveStateIn(tlb_old, currentProcess->excStVec[type*2]);
break;
case SPECPGMT:
saveStateIn(pgmtrap_old, currentProcess->excStVec[type*2]);
break;
case SPECSYSBP:
saveStateIn(sysbp_old, currentProcess->excStVec[type*2]);
break;
}
/* Carico lo stato dalla newarea */
LDST(currentProcess->excStVec[(type*2)+1]);
}else{
/* Altrimenti tratto come una SYS2 */
terminateProcess(currentProcess);
scheduler();
}
}
}
开发者ID:illbexyz,项目名称:kaya-os-uarm,代码行数:25,代码来源:exceptions.c
示例10: main
int main (int argc, char *argv []) {
int listen_fd, port;
int client_fd;
socklen_t socket_length;
struct sockaddr_in client_socket;
pthread_mutex_init(&mutex_lock, NULL);
init_cache();
Signal (SIGPIPE, SIG_IGN);
if (argc != 2) {
fprintf(stderr, "usage: %s <port>\n", argv[0]);
exit(0);
}
port = atoi(argv[1]);
listen_fd = Open_listenfd(port);
socket_length = sizeof(client_socket);
while (1) {
client_fd = Accept(listen_fd, (SA*)&client_socket, &socket_length);
scheduler(client_fd);
}
pthread_mutex_destroy(&mutex_lock);
clean_cache();
}
开发者ID:fxiang,项目名称:proxylab,代码行数:25,代码来源:proxy.c
示例11: GCFromMutator
/* Does not return - goes to scheduler */
void
GCFromMutator(Thread_t* curThread)
{
Proc_t *proc = (Proc_t *) curThread->proc;
mem_t alloc = (mem_t) curThread->saveregs[ALLOCPTR];
mem_t limit = (mem_t) curThread->saveregs[ALLOCLIMIT];
mem_t sysAllocLimit = proc->allocLimit;
/* Put registers in stacklet */
int i;
Stacklet_t *stacklet = CurrentStacklet(curThread->stack);
volatile reg_t* primaryRegs =
&stacklet->bottomBaseRegs[primaryStackletOffset == 0 ? 0 : 32];
for (i=0; i<32; i++)
primaryRegs[i] = curThread->saveregs[i];
/*
Check that we are running on own stack and allocation pointers
consistent
*/
if (paranoid)
assert(proc == (getProc())); /* getProc is slow */
assert(proc->userThread == curThread);
assert((proc->stack - (int) (&proc)) < 1024) ;
assert((limit == sysAllocLimit) || (limit == StopHeapLimit));
assert(alloc <= sysAllocLimit);
/* ReleaseJob(proc) */
/* Update processor's info, GCRelease thread, but don't unmap */
UpdateJob(proc);
procChangeState(proc, Scheduler, 1003);
scheduler(proc);
DIE("scheduler returned");
}
开发者ID:RobertHarper,项目名称:TILT-Compiler,代码行数:35,代码来源:gc.c
示例12: timer_handler
// This is executed as part of the current running thread
// Activities to be done :
// 1. System time updating.
// 2. Timer object value decrementing and setting the flag
// for time out event processing.
// 3. Set if necessary priority recomputation flag.
// 4. Update the time quantum left and cpu usage for the current thread.
// If necessary call the scheduler function after enablig the timer.
// flags : runrun, kprunrun, priocompute, timeoutflag
void timer_handler (int irq)
{
unsigned long oflags;
/* Update system time value. HZ = 50 */
millesecs += 20;
if (millesecs >= 1000)
{
secs++;
millesecs -= 1000;
priocompute = 1;// Once in every one second recompute
//priorities by applying decay factor.
}
// Without locking only the first timer object is observed.
if (timers != NULL)
{
timers->timer_count -= 20;
if (timers->timer_count <= 0) timeoutflag = 1;
}
// Update current thread cpu usage statistics
rr_cl_tick((struct kthread *)current_thread);
if (current_thread->kt_schedinf.sc_tqleft <= 0 || runrun == 1 || kprunrun == 1)
{
// Start scheduler function
CLI;
enable_timer();
scheduler();
STI;
}
return;
}
开发者ID:sunank200,项目名称:ATOM-OS,代码行数:42,代码来源:timer.c
示例13: schedule5
// Not possible to add tasks in a scheduled task atm
void
schedule5(TaskManager::ThreadManager& manager) {
TaskManager::Scheduler scheduler(2, manager);
bool stop = false;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
TaskManager::Task task([&stop, &scheduler]() {
unsigned int i = 1;
while (!stop) {
auto future = scheduler.runIn([i]() {
return std::to_string(i) + " second elapsed";
},
std::chrono::milliseconds(60));
std::cout << future.get() << " " << (int)stop << std::endl;
++i;
}
});
task.setStopFunction([&stop]() {
stop = true;
});
std::this_thread::sleep_for(std::chrono::milliseconds(10));
scheduler.runAt(task, std::chrono::steady_clock::now());
getchar();
}
开发者ID:Tastyep,项目名称:TaskManager,代码行数:26,代码来源:main.cpp
示例14: start_scheduler
void start_scheduler()
{
SchedulerTask.sigint_handler = NULL;
SchedulerTask.tss.cr3 = (uint32_t)PAGE_DIR;
SchedulerTask.tss.eflags = 0xE0000011;
GDT[7].limit_low = 0x67;
GDT[7].base_low = (uint32_t)&SchedulerTask.tss & 0xFFFF;
GDT[7].base_mid = ((uint32_t)&SchedulerTask.tss & 0xFF0000) >> 16;
GDT[7]._FIXED_0 = 9;
GDT[7]._FIXED_1 = 0;
GDT[7].priv_level = 0;
GDT[7].present = 1;
GDT[7].limit_high = 0;
GDT[7].AVL_to_sys = 0;
GDT[7]._FIXED_2 = 0;
GDT[7].big = 0;
GDT[7].granularity = 0;
GDT[7].base_high = (uint32_t)&SchedulerTask.tss >> 24;
__asm__ volatile(
".intel_syntax noprefix;"
"ltr ax;"
".att_syntax;"
::"a"(7 << 3):
);
scheduler();
}
开发者ID:richardtsai,项目名称:homework,代码行数:26,代码来源:scheduler.c
示例15: dispatcher_body
void dispatcher_body()
{
int err, t0, t1;
task_t* next; // Tarefa que ocupara o processador.
enable_preemption(0);
// Caso haver alguma tarefa na lista de prontas
// o while eh executado.
while (list_size(ready_list) > 0) {
t0 = systime();
next = scheduler();
if (next) {
ticks = 20;
enable_preemption(1);
t1 = systime();
curr_task->proc_time += t0 - t1;
t0 = systime();
err = task_switch(next);
t1 = systime();
next->proc_time += t1 - t0;
if (err == -1) {
perror("dispatcher_body: task_switch failed.\n");
return;
}
}
}
// Finaliza o dispatcher, voltando para o main.
task_exit(0);
}
开发者ID:bmeneguele,项目名称:sist-op,代码行数:35,代码来源:task.c
示例16: TestScheduler
void TestScheduler(const char* msg, const PrimeMap& value, time_sec serialTime)
{
ticks_t start = now();
SCHEDULER scheduler(CoreCount);
std::map<std::size_t, std::size_t> tasks;
for (std::size_t i = 0; i < Count; i++)
{
#ifdef VOID_TEST
tasks[i] = scheduler.add_task([i]() -> void {Test(i); });
tasks[MaxNum - i] = scheduler.add_task([i]() -> void {Test(MaxNum - i); });
#else
tasks[i] = scheduler.add_task([i]() -> bool { return IsPrime(i); });
tasks[MaxNum - i] = scheduler.add_task([i]() -> bool { return IsPrime(MaxNum - i); });
#endif
}
for (auto i = tasks.begin(); i != tasks.end(); ++i)
{
#ifdef VOID_TEST
scheduler.get_task_result(i->second);
#else
if (value.at(i->first) != scheduler.get_task_result(i->second))
throw 0;
#endif
}
time_sec parallelTime = ticks_to_time(now() - start);
std::cout << msg << " time = " << parallelTime << " [s] - Serial time portion = " << parallelTime / (serialTime / 100.0) << " [%]" << std::endl;
std::cout << msg << " calculation correct" << std::endl;
}
开发者ID:Dzejrou,项目名称:School-Work,代码行数:29,代码来源:Source.cpp
示例17: scheduler_
thread_pool_os_executor<Scheduler>::thread_pool_os_executor(
std::size_t num_punits, std::string const& affinity_desc)
: scheduler_(nullptr),
executor_name_(get_unique_name()),
notifier_(get_notification_policy(executor_name_.c_str())),
pool_(nullptr),
num_threads_(num_punits)
{
if (num_punits > hpx::threads::hardware_concurrency())
{
HPX_THROW_EXCEPTION(bad_parameter,
"thread_pool_os_executor<Scheduler>::thread_pool_os_executor",
"max_punit shouldn't be larger than number of available "
"OS-threads");
return;
}
std::unique_ptr<Scheduler> scheduler(new Scheduler(num_punits));
scheduler_ = scheduler.get();
pool_.reset(new threads::detail::scheduled_thread_pool<Scheduler>(
std::move(scheduler), notifier_, 0, executor_name_.c_str()));
std::unique_lock<mutex_type> lk(mtx_);
pool_->init(num_threads_, 0);
if (!pool_->run(lk, num_threads_))
{
lk.unlock();
HPX_THROW_EXCEPTION(invalid_status,
"thread_pool_os_executor<Scheduler>::thread_pool_os_executor",
"couldn't start thread_pool");
}
}
开发者ID:K-ballo,项目名称:hpx,代码行数:34,代码来源:thread_pool_os_executors.cpp
示例18: KOS
KOS() {
/* Semaphores */
writeOK = make_kt_sem(0);
writers = make_kt_sem(1);
readers = make_kt_sem(1);
nElem = make_kt_sem(0);
consoleWait = make_kt_sem(0);
/* Generics */
sys_stop_read = 0;
current_pid = 0;
console_size = 256;
buffer_head, buffer_tail;
// Zero out memory
bzero(main_memory, MemorySize);
bzero(memory_space_array, 8);
/* Initializers */
currentProcess = (PCB *) malloc(sizeof(PCB));
initialize_console_buffer(&buffer_head, &buffer_tail);
readyQ = new_dllist();
found_node = make_jrb();
pid_tree = make_jrb();
kt_fork(initialize_user_process, (void *)kos_argv);
kt_fork(console_buf_read, (void *)kos_argv[0]);
kt_joinall();
start_timer(10);
scheduler();
}
开发者ID:Styxx,项目名称:CS170-W16,代码行数:31,代码来源:kos.c
示例19: main
int main(void)
{
wdtdrv_disable();
Clear_prescaler();
scheduler();
return 0;
}
开发者ID:epsil,项目名称:tunge,代码行数:7,代码来源:main.c
示例20: scheduler
// 다음 수행될 task를 선택하는 함수
void scheduler(void)
{
TaskInfo task;
// gh_sch의 running_task가 가르키고 있는 taskinfo 받음
task = task_get_runningtask();
switch ( task->status ) {
// task상태가 TASK_RUN이나 TASK_SLEEP이면 선택됨
case TASK_RUN:
case TASK_SLEEP:
break;
// task상태가 TASK_KILL이면 delete하고, swiching함수 다시 호출
case TASK_KILL:
task_delete(task);
scheduler();
break;
// task상태가 TASK_YIELD이면 상태를 TASK_RUN으로 바꾸고 선택됨
case TASK_YIELD:
task->status = TASK_RUN;
break;
// task상태가 TASK_READY이면 싱테를 TASK_RUN으로 바꾸고 선택됨
case TASK_READY:
task->status = TASK_RUN;
break;
}
// gh_sch의 running_task를 linkedlist의 다음 task로 설정
task_next();
}
开发者ID:kdy707,项目名称:Study_Kernel,代码行数:29,代码来源:schedule.c
注:本文中的scheduler函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论