广西钦州住房与城乡建设局网站,网站备案人授权书,学院网站建设成果,wordpress修改器进程相关函数解释
1、前言 这一篇博客是为了我其他关于多线程同步实验准备的#xff0c;遇到不明白函数可以方便查阅#xff0c;并附上函数相关链接。 #xff08;虽然看着会很困#xff0c;但是还是多看看 #xff09; 2、相关函数 在说明函数之前先把函数中参数类型先大…进程相关函数解释
1、前言 这一篇博客是为了我其他关于多线程同步实验准备的遇到不明白函数可以方便查阅并附上函数相关链接。 虽然看着会很困但是还是多看看 2、相关函数 在说明函数之前先把函数中参数类型先大致说明一下 参数类型解释 HANDLE类型可以说是最常见到了 HANDLE HANDLE句柄是Windows操作系统中的一个概念。在Windows程序中有各种各样的资源窗口、图标、光标等系统在创建这些资源时会为它们分配内存并返回标示这些资源的标示号即句柄。句柄指的是一个核心对象在某一个进程中的唯一索引而不是指针。由于地址空间的限制句柄所标识的内容对进程是不可见的只能由操作系统通过进程句柄列表来进行维护。句柄列表每个进程都要创建一个句柄列表这些句柄指向各种系统资源比如信号量线程和文件等进程中的所有线程都可以访问这些资源。 LPCTSTR类型 LPCTSTR链接 L表示long指针 这是为了兼容Windows 3.1等16位操作系统遗留下来的在win32中以及其他的32位操作系统中 long指针和near指针及far修饰符都是为了兼容的作用。没有实际意义。 P表示这是一个指针 C表示是一个常量 T表示在Win32环境中 有一个_T宏 STR表示这个变量是一个字符串 LPCTSTR就表示一个指向const对象的指针 LPTSTR也差不多只是不是指向const对象的 LPSECURITY_ATTRIBUTES类型 LPSECURITY_ATTRIBUTES链接 LPSECURITY_ATTRIBUTES结构包含一个对象的安全描述符并指定检索到指定这个结构的句柄是否是可继承的。 DWORD类型 DWORD链接 dword全称Double Word每个word为2个字节的长度是指计算机中数值的位数(4字节32位)。 LPVOID类型 LPVOID LPVOID是一个没有类型的指针也就是说你可以将LPVOID类型的变量赋值给任意类型的指针比如在参数传递时就可以把任意类型传递给一个LPVOID类型为参数的方法然后在方法内再将这个“任意类型”从传递时的“LPVOID类型”转换回来。 LPSTARTUPINFO类型 LPSTARTUPINFO 用于指定新进程的主窗口特性的一个结构也就是决定进程的窗体如何显示 LPPROCESS_INFORMATION LPPROCESS_INFORMATION 在创建进程时相关的数据结构之一该结构返回有关新进程及其主线程的信息 size_t size_t size_t 类型定义在cstddef头文件中该文件是C标准库的头文件stddef.h的C版。它是一个与机器相关的unsigned类型其大小足以保证存储内存中对象的大小。在64位系统中为long long unsigned int非64位系统中为long unsigned int。 LPTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE是一种函数指针该函数指针指向一个函数通知宿主某个线程已开始执行。 CRITICAL_SECTION CRITICAL_SECTION critical section是每个线程中访问临界资源的那段代码不论是硬件临界资源还是软件临界资源多个线程必须互斥地对它进行访问。 例如
CRITICAL_SECTION CS_DATA;函数部分
CreateProcess函数 CreateProcess函数 CreateProcess用来创建一个新的进程和它的主线程这个新进程运行指定的可执行文件。 BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATIONlpProcessInformation
);2、函数参数解释 lpApplicationName 指向一个NULL结尾的、用来指定可执行模块的字符串。可以简单理解为这里参数是一个可执行文件的路径之后会调用这个路径上的可执行文件 lpCommandLine 指向一个以NULL结尾的字符串该字符串指定要执行的命令行。 这个参数可以为空那么函数将使用lpApplicationName参数指定的字符串当做要运行的程序的命令行。 如果lpApplicationName和lpCommandLine参数都不为空那么lpApplicationName参数指定将要被运行的模块lpCommandLine参数指定将被运行的模块的命令行。新运行的进程可以使用GetCommandLine函数获得整个命令行。C语言程序可以使用argc和argv参数argc表示命令行参数个数而argv为存储命令行参数的数组。 其实这个就是个命令行参数参数可以为NULL,也可以为一个const char类型的值允许你通过参数给程序传一些变量 lpProcessAttributes 指向一个SECURITY_ATTRIBUTES结构体这个结构体决定是否返回的句柄可以被子进程继承。如果lpProcessAttributes参数为NULL则表示使用默认安全性不可以被子进程继承 一般为NULL lpThreadAttributes 指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中NULL使用默认安全性不可以被子线程继承否则需要定义一个结构体将它的bInheritHandle成员初始化为TRUE 跟lpProcessAttributes一样不过这个参数决定的是线程是否被继承.通常置为NULL bInheritHandles 指示新进程是否从调用进程处继承了句柄。 如果参数的值为真调用进程中的每一个可继承的打开句柄都将被子进程继承。被继承的句柄与原进程拥有完全相同的值和访问权限。 dwCreationFlags 指定附加的、用来控制优先类和进程的创建的标志。 有很多定义好的不同创建标志宏不同的创建标志会给进程不同的创建方式和优先级区别。一般为NULL lpEnvironment 指向一个新进程的环境块。如果此参数为空新进程使用调用进程的环境。 一个环境块存在于一个由以NULL结尾的字符串组成的块中这个块也是以NULL结尾的。每个字符串都是namevalue的形式。 因为相等标志被当做分隔符所以它不能被环境变量当做变量名。 与其使用应用程序提供的环境块不如直接把这个参数设为空 lpCurrentDirectory 指向一个以NULL结尾的字符串这个字符串用来指定子进程的工作路径。这个字符串必须是一个包含驱动器名的绝对路径。如果这个参数为空新进程将使用与调用进程相同的驱动器和目录(也就是当前进程目录)。 lpStartupInfo 指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体。 lpProcessInformation 指向一个用来接收新进程的识别信息的PROCESS_INFORMATION结构体。 CreateThread函数 CreateThread函数 CreateThread链接 CreateThread是一种微软在Windows API中提供了建立新的线程的函数该函数在主线程的基础上创建一个新线程。线程终止运行后线程对象仍然在系统中必须通过CloseHandle函数来关闭该线程对象 HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
)函数参数解释 lpThreadAttributes 指向SECURITY_ATTRIBUTES型态的结构的指针。在Windows 98中忽略该参数。在Windows NT中NULL使用默认安全性不可以被子线程继承否则需要定义一个结构体将它的bInheritHandle成员初始化为TRUE 跟lpProcessAttributes一样不过这个参数决定的是线程是否被继承.通常置为NULL dwStackSize: 设置初始栈的大小以字节为单位如果为0那么默认将使用与调用该函数的线程相同的栈空间大小。任何情况下Windows根据需要动态延长堆栈的大小。 lpStartAddress: 指向线程函数的指针,函数名称没有限制 线程有两种声明方式
1DWORD WINAPI 函数名 (LPVOID lpParam); //标准格式DWORD WINAPI 函数名 (LPVOID lpParam)
{return 0;
}
CreateThread(NULL, 0, 函数名, 0, 0, 0);
2void 函数名();
使用void 函数名()此种线程声明方式时lpStartAddress需要加入LPTHREAD_START_ROUTINE转换如void 函数名()
{return;
}
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)函数名, 0, 0, 0);lpParameter 向线程函数传递的参数是一个指向结构的指针不需传递参数时为NULL。 dwCreationFlags 指定附加的、用来控制优先类和进程的创建的标志。 有很多定义好的不同创建标志宏不同的创建标志会给进程不同的创建方式和优先级区别。一般为NULL lpThreadId:保存新线程的id。 返回值函数成功返回线程句柄函数失败返回false。若不想返回线程ID,设置值为NULL。 CloseHandle函数 CloseHandle函数 关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。在CreateThread这是创建线程函数后面会有成功之后会返回一个hThread的handle且内核对象的计数加1CloseHandle之后引用计数减1当变为0时系统删除内核对象。 若在线程执行完之后没有调用CloseHandle在进程执行期间将会造成内核对象的泄露相当于句柄泄露但不同于内存泄露这势必会对系统的效率带来一定程度上的负面影响。但当进程结束退出后系统会自动清理这些资源。 BOOL CloseHandle(
HANDLE hObject
);
参数
hObject 代表一个已打开对象句柄。
返回值
TRUE执行成功
FALSE执行失败可以调用GetLastError()获知失败原因WaitForSingleObject函数 WaitForSingleObject函数 WaitForSingleObject函数用来检测hHandle事件的信号状态在某一线程中调用该函数时线程暂时挂起如果在挂起的dwMilliseconds毫秒内线程所等待的对象变为有信号状态则该函数立即返回如果时间已经到达dwMilliseconds毫秒但hHandle所指向的对象还没有变成有信号状态函数照样返回。 DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);函数参数解释 hHandle hHandle对象句柄。可以指定一系列的对象如Event、Job、Memory resource notification、Mutex、Process、Semaphore、Thread、Waitable timer等。 dwMilliseconds dwMilliseconds为定时时间间隔单位为milliseconds毫秒.如果指定一个非零值函数处于等待状态直到hHandle标记的对象被触发或者时间到了。如果dwMilliseconds为0对象没有被触发信号函数不会进入一个等待状态它总是立即返回。如果dwMilliseconds为INFINITE对象被触发信号后函数才会返回。 我们常常会设为INFINTE,因为我们经常使用WaitForSingleObject函数为多线程里的P操作起到一个上锁作用 WaitForMultipleObjects函数 WaitForMultipleObjects函数 WaitForMultipleObjects是Windows中的一个功能非常强大的函数几乎可以等待Windows中的所有的内核对象简单说WaitForSingleObject函数可以等待单个线程 WaitForMultipleObjects可以等待一组线程程 DWORD WaitForMultipleObjects(
DWORD nCount,
const HANDLE* lpHandles,
BOOL bWaitAll,
DWORD dwMilliseconds
);函数参数解释 nCount lpHandles指向的数组中的对象句柄数。对象句柄的最大数量为MAXIMUM_WAIT_OBJECTS。此参数不能为零。 lpHandles一组对象句柄。该数组可以包含不同类型对象的句柄。它可能不包含同一句柄的多个副本。 如果其中一个句柄在等待仍处于暂挂状态时关闭则该函数的行为未定义。 句柄必须具有SYNCHRONIZE访问权限。 bWaitAll 如果此参数为TRUE则在lpHandles数组中的所有对象的状态发出信号时该函数返回。如果为FALSE则当任何一个对象的状态设置为信号时该函数返回。在后一种情况下返回值表示其状态导致函数返回的对象。 dwMilliseconds 超时间隔以毫秒为单位。如果指定了非零值则该函数将一直等到指定的对象发出信号或经过间隔。如果dwMilliseconds为零则如果未发出指示对象则该函数不会进入等待状态;它总是立即返回。如果dwMilliseconds是INFINITE则仅在发出指定对象信号时才返回该函数。 例如这里这句意思为等待MAX_THREAD个h_thread句柄对象这里为线程
全部发出信号即全部线程都结束了才停止挂起状态
WaitForMultipleObjects(MAX_THREAD, h_thread, TRUE, -1);CreateMutex函数 CreateMutex函数 CreateMutex链接 CreateMutex是一个计算机函数作用是找出当前系统是否已经存在指定进程的实例。如果没有则创建一个互斥体我们用它作为互斥量进行上锁操作 HANDLE CreateMutex(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
BOOL bInitialOwner, // 初始化互斥对象的所有者
LPCTSTR lpName // 指向互斥对象名的指针
);函数参数解释 lpMutexAttributes 指定一个SECURITY_ATTRIBUTES结构或传递零值将参数声明为ByVal As Long并传递零值表示使用不允许继承的默认描述符 bInitialOwner 如创建进程希望立即拥有互斥体则设为TRUE。一个互斥体同时只能由一个线程拥有 lpName指定互斥体对象的名字。用vbNullString创建一个未命名的互斥体对象。如已经存在拥有这个名字的一个事件则打开现有的已命名互斥体。这个名字可能不与现有的事件、信号机、可等待计时器或文件映射相符 OpenMutex函数 CreateMutex函数 OpenMutex函数 OpenMutex函数为现有的一个已命名互斥体对象创建一个新句柄。 一般在多线程同步里不太会用到 HANDLE OpenMutex(
DWORD dwDesiredAccess, // access
BOOL bInheritHandle, // inheritance option
LPCTSTR lpName // object name
);函数参数解释 dwDesiredAccess MUTEX_ALL_ACCESS 请求对互斥体的完全访问 MUTEX_MODIFY_STATE 允许使用 ReleaseMutex 函数 SYNCHRONIZE 允许互斥体对象同步使用 bInheritHandle : 如希望子进程能够继承句柄则为TRUE lpName 要打开对象的名字 返回值如执行成功返回对象的句柄零表示失败。若想获得更多错误信息请调用GetLastError函数。
ReleaseMutex函数 ReleaseMutex函数 ReleaseMutex函数 ReleaseMutex函数的功能是释放互斥对象的控制权 一个线程释放了互斥对象的控制权后如果其他进程在等待互斥对象置位则等待的线程可以得到该互斥对象等待函数返回互斥对象被新的线程所拥有。我们用它来解除上锁在线程控制中CreateMutex函数和ReleaseMutex函数是一对PV操作 BOOL WINAPI ReleaseMutex(
HANDLE hMutex//hMutexHANDLE制定一个互斥体的句柄。
);CreateSemaphore函数 CreateSemaphore函数 CreateSemaphore函数 创建或打开命名或未命名的信号量对象。 Semaphore是另一个同步问题机制不论是Event或Mutex其他Process在执行WaitForSingleObject时就看当时的对象是Signal或UnSignal而决定是否等待而Semaphore也相同但是它要变成Signal /UnSignal的状态却有些不同它是提供一个计数值它允许在这个计数值之内任何执行到WaitForSingleObject的Thread都不会停下来而且每执行WaitForSingleObject一次计数值就减一当计数值变成0时该Semaphore才会处於UnSignal的状态而某个Thread ReleaseSemaphore时便会将计数值增加以便其他的Thread或本身可得Signal的讯号而使WaitForSingleObject停止等待简单来说用互斥量Mutex等实现WaitForSingleObject等待是一个开关而用信号量Semaphore是一个范围只有在0还有最大值情况才会触发开关也就是等待挂起或者进行具体例子下面介绍。 HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCT STRlpName
);函数参数解释 lpSemaphoreAttributes 指定一个SECURITY_ATTRIBUTES结构或传递零值将参数声明为ByVal As Long并传递零值——表示采用不允许继承的默认描述符。该参数定义了信号量的安全特性 lInitialCount 设置信号量的初始计数。可设置零到lMaximumCount之间的一个值初始值 lMaximumCount 设置信号量的最大计数最大值 lpName 指定信号量对象的名称。用vbNullString可创建一个未命名的信号量对象。如果已经存在拥有这个名字的一个信号量就直接打开现成的信号量。这个名字可能不与一个现有的互斥体、事件、可等待计时器或文件映射的名称相符 具体例子
HANDLE Semaphore CreateSemaphore(NULL, 0, 10, NULL);
WaitForSingleObject(Semaphore, INFINITE);
我们创建了一个句柄Semaphore来作为信号量
其中他初始值为0,最大值为10当我们WaitForSingleObject
一般mutex情况下只有第一个线程会进入挂起
之后的得等解锁才可以继续而信号量这里会有一个计数
每次WaitForSingleObject时候初始值加1如果达到最大值了才会上锁
这样就给了我们一个0~10 的范围具体应用呢
比如我们在多线程里的消费者生产者问题中
物品有很多件这样的话如果用互斥量就不行了
可以选择信号量设置范围当物品满了等待不再填入
或者物品空了不能再购买这些用信号量机制都能轻易解决
ReleaseSemaphore函数 ReleaseSemaphore函数 ReleaseSemaphore函数 与 WaitForSingleObject函数对应WaitForSingleObject函数会对指定信号量减1ReleaseSemaphore函数用于对指定的信号量增加指定的值。与互斥量机制类型可以实现PV操作 BOOL ReleaseSemaphore(
HANDLE hSemaphore,
LONG lReleaseCount,
LPLONG lpPreviousCount
);函数参数解释 hSemaphore 所要操作的信号量对象的句柄这个句柄是CreateSemaphore或者OpenSemaphore函数的返回值。这个句柄必须有SEMAPHORE_MODIFY_STATE 的权限。 lReleaseCount [输入参数]这个信号量对象在当前基础上所要增加的值这个值必须大于0如果信号量加上这个值会导致信号量的当前值大于信号量创建时指定的最大值那么这个信号量的当前值不变同时这个函数返回FALSE; lpPreviousCount [输出参数]指向返回信号量上次值的变量的指针如果不需要信号量上次的值那么这个参数可以设置为NULL;返回值如果成功返回TRUE,如果失败返回FALSE,可以调用GetLastError函数得到详细出错信息 ResumeThread函数 ResumeThread函数 ResumeThread函数 使线程的挂起时间计数减一。创建一个挂起的线程或者手动挂起一个线程后调用。调用该函数后线程不一定会立刻执行而是由操作系统继续调度直到计数为0系统为其分配资源时才开始执行。 DWORD WINAPI ResumeThread(_In_ HANDLE hThread);
hthread是要重新启动的线程的句柄。
此句柄必须具有线程“挂起”恢复访问权限。注意事项
resumeThread函数检查主题线程的挂起计数。如果挂起计数为零则线程当前未挂起。否则主题线程的挂起计数将减少。如果结果值为零则继续执行主题线程。
如果返回值为零则指定的线程没有挂起。如果返回值为1则指定的线程已挂起但已重新启动。如果返回值大于1则指定的线程仍将挂起。
请注意在报告调试事件时报告进程中的所有线程都将被冻结。调试程序需要使用suspendthread和resumethread函数来限制可以在进程内执行的线程集。通过挂起进程中除报告调试事件的线程外的所有线程可以“单步”处理单个线程。如果挂起其他线程则继续操作不会释放这些线程。InitializeCriticalSection函数 InitializeCriticalSection函数 InitializeCriticalSection函数 InitializeCriticalSection函数用来初始化一个临界资源对象。“临界区”CCriticalSection 是临界资源对象指针该函数无返回值。单进程的各个线程可以使用临界资源对象来解决同步互斥问题该对象不能保证哪个线程能够获得到临界资源对象该系统能公平的对待每一个线程。 VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection )lpCriticalSection 临界资源对象指针。实例
InitializeCriticalSection(CS_DATA);
InitializeCriticalSection的初始化后才能使用
而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下EnterCriticalSection函数和LeaveCriticalSection函数 EnterCriticalSection函数和LeaveCriticalSection函数 EnterCriticalSection函数和LeaveCriticalSection函数 多个线程操作相同的数据时一般是需要按顺序访问的否则会引导数据错乱无法控制数据变成随机变量。为解决这个问题就需要引入互斥变量让每个线程都按顺序地访问变量。这样就需要使用EnterCriticalSection和LeaveCriticalSection函数。 函数 EnterCriticalSection 和 LeaveCriticalSection 声明如下
void WINAPI
EnterCriticalSection(
_inout LPCRITICAL_SECTION lpCriticalSection
);
void WINAPI LeaveCriticalSection(
_Inout_LPCRITICAL_SECTION lpCriticalSection
);
是多线程中用来确保同一时刻只有一个线程操作被保护的数据的操作函数相关的多线程数据操作函数还有InitializeCriticalSection(cs);//初始化临界区
EnterCriticalSection(cs);//进入临界区
//操作数据
MyMoney*10;//所有访问MyMoney变量的程序都需要这样写Enter.. Leave...
LeaveCriticalSection(cs);//离开临界区
DeleteCriticalSection(cs);//删除临界区3、多线程同步进程互斥相关的博客 下面会附上链接都是自己写的可以运行的c程序大家可以一遍试一下一边看 1、哲学家进餐 2、兔子吃草同步算法 3、生产者消费者同步问题 4、理发师问题 5、写者优先的读者写者算法 6、读者优先的读者写者算法 7、进程互斥 文章转载自: http://www.morning.zmbzl.cn.gov.cn.zmbzl.cn http://www.morning.hmpxn.cn.gov.cn.hmpxn.cn http://www.morning.txfzt.cn.gov.cn.txfzt.cn http://www.morning.bctr.cn.gov.cn.bctr.cn http://www.morning.spnky.cn.gov.cn.spnky.cn http://www.morning.ddzqx.cn.gov.cn.ddzqx.cn http://www.morning.rbjth.cn.gov.cn.rbjth.cn http://www.morning.nzlqt.cn.gov.cn.nzlqt.cn http://www.morning.kpbq.cn.gov.cn.kpbq.cn http://www.morning.yfmlj.cn.gov.cn.yfmlj.cn http://www.morning.ylxgw.cn.gov.cn.ylxgw.cn http://www.morning.btqqh.cn.gov.cn.btqqh.cn http://www.morning.wjrtg.cn.gov.cn.wjrtg.cn http://www.morning.qjlnh.cn.gov.cn.qjlnh.cn http://www.morning.brcdf.cn.gov.cn.brcdf.cn http://www.morning.nynyj.cn.gov.cn.nynyj.cn http://www.morning.fxzw.cn.gov.cn.fxzw.cn http://www.morning.lwyqd.cn.gov.cn.lwyqd.cn http://www.morning.qyrnp.cn.gov.cn.qyrnp.cn http://www.morning.hyfrd.cn.gov.cn.hyfrd.cn http://www.morning.dwwlg.cn.gov.cn.dwwlg.cn http://www.morning.ggfdq.cn.gov.cn.ggfdq.cn http://www.morning.wmdbn.cn.gov.cn.wmdbn.cn http://www.morning.mhlkc.cn.gov.cn.mhlkc.cn http://www.morning.lxbml.cn.gov.cn.lxbml.cn http://www.morning.wqsjx.cn.gov.cn.wqsjx.cn http://www.morning.dbrnl.cn.gov.cn.dbrnl.cn http://www.morning.fwllb.cn.gov.cn.fwllb.cn http://www.morning.yrycb.cn.gov.cn.yrycb.cn http://www.morning.lwxsy.cn.gov.cn.lwxsy.cn http://www.morning.rwjh.cn.gov.cn.rwjh.cn http://www.morning.wslpk.cn.gov.cn.wslpk.cn http://www.morning.ztnmc.cn.gov.cn.ztnmc.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.yubkwd.cn.gov.cn.yubkwd.cn http://www.morning.sfgzx.cn.gov.cn.sfgzx.cn http://www.morning.lftpl.cn.gov.cn.lftpl.cn http://www.morning.fstesen.com.gov.cn.fstesen.com http://www.morning.sgfpn.cn.gov.cn.sgfpn.cn http://www.morning.mprpx.cn.gov.cn.mprpx.cn http://www.morning.ftldl.cn.gov.cn.ftldl.cn http://www.morning.msbpb.cn.gov.cn.msbpb.cn http://www.morning.krdb.cn.gov.cn.krdb.cn http://www.morning.hwcln.cn.gov.cn.hwcln.cn http://www.morning.gstmn.cn.gov.cn.gstmn.cn http://www.morning.mmqhq.cn.gov.cn.mmqhq.cn http://www.morning.ntnml.cn.gov.cn.ntnml.cn http://www.morning.lfbsd.cn.gov.cn.lfbsd.cn http://www.morning.nlwrg.cn.gov.cn.nlwrg.cn http://www.morning.spdyl.cn.gov.cn.spdyl.cn http://www.morning.gcqs.cn.gov.cn.gcqs.cn http://www.morning.ftmly.cn.gov.cn.ftmly.cn http://www.morning.ylklr.cn.gov.cn.ylklr.cn http://www.morning.tynqy.cn.gov.cn.tynqy.cn http://www.morning.bpknt.cn.gov.cn.bpknt.cn http://www.morning.hcqd.cn.gov.cn.hcqd.cn http://www.morning.qdlnw.cn.gov.cn.qdlnw.cn http://www.morning.zyrcf.cn.gov.cn.zyrcf.cn http://www.morning.lhldx.cn.gov.cn.lhldx.cn http://www.morning.haibuli.com.gov.cn.haibuli.com http://www.morning.pngfx.cn.gov.cn.pngfx.cn http://www.morning.bhbxd.cn.gov.cn.bhbxd.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.ggqcg.cn.gov.cn.ggqcg.cn http://www.morning.wtbzt.cn.gov.cn.wtbzt.cn http://www.morning.jqjnl.cn.gov.cn.jqjnl.cn http://www.morning.pccqr.cn.gov.cn.pccqr.cn http://www.morning.zlkps.cn.gov.cn.zlkps.cn http://www.morning.ksggr.cn.gov.cn.ksggr.cn http://www.morning.gnlyq.cn.gov.cn.gnlyq.cn http://www.morning.clbzy.cn.gov.cn.clbzy.cn http://www.morning.ndnhf.cn.gov.cn.ndnhf.cn http://www.morning.ryfq.cn.gov.cn.ryfq.cn http://www.morning.hkswt.cn.gov.cn.hkswt.cn http://www.morning.srnth.cn.gov.cn.srnth.cn http://www.morning.cqwb25.cn.gov.cn.cqwb25.cn http://www.morning.xtqr.cn.gov.cn.xtqr.cn http://www.morning.mrnnb.cn.gov.cn.mrnnb.cn http://www.morning.hdlhh.cn.gov.cn.hdlhh.cn http://www.morning.wngpq.cn.gov.cn.wngpq.cn