多线程学习笔记

线程标识符类型:pthread_t
获取线程id:pthread_self()



.创造线程:
int pthread_create(pthread_t *restrict,const pthread_attr_t *restrict attr,void*(*start_routine)(void *),void *restrict arg)
第一个参数:新线程的id,如果成功则新线程的id回填充到tid指向的内存
第二个参数:线程属性(调度策略,继承性,分离性...
第三个参数:回调函数(新线程要执行的函数)
第四个参数:回调函数的参数
返回值:成功返回0,失败返回错误码
注意:编译时需要链接libpthread
例子:
void print_id(char *s)
{
    pid_t pid;
    pthread_t tid;
    pid = getpid();
    tid = pthread_self();
    printf("%s pid is %u.tid is0x%x\n",s,pid,tid);
}
void *pthread_fun(void *arg)
{
    print_id(arg);
    return (void *)0;
}
int main()
{
    pthread_t ntid;
    int err;
    err =pthread_creat(&tid,NULL,thread_fun,"new thread");
    if(err!=0)
    {
        printf("creat new threadfailed\n");
        return 0;
    }
    print_id("mainthread:");
    sleep(2);
    return 0;
}






.线程的回收
1.
线程的分离属性:分离一个正在运行的线程并不影响它,仅仅是通知系统当前线程结束时,其所属资源可以回收。一个没有被分离的线程在终止时会保留它的虚拟内存,包括他们的堆2.栈和其他系统资源,有时这种线程被称为僵尸线程,创建线程时默认时非分离的。
3.
如果线程具有分离属性,线程终止时会被立刻回收,回收将释放掉所有在线程终止时未释放的系统资源和进程资源
4.
终止被分离的线程会释放所有的系统资源,但是你务必释放由该线程占有的程序资源。由malloc或者mmap分配的内存可以在任何时候由任何线程释放,条件变量,互斥量,信号灯可以由任何线程销毁,只要他们被解锁了或者没有线程等待。但是只有互斥量的主人才能解锁它,所以在线程终止前,你需要解锁互斥量。







.线程退出
1.
如果进程中的任意一个线程调用了exit,_Exit,_exit那么整个进程就会终止
2.
普通的单个线程有以下三种方式退出,这样不会终止进程:
   
1)从启动例程返回,返回值是线程的退出码(即调用return函数)
   
2)线程可以被统一进程中的其他线程取消
   
3)线程调用pthread_exit(void *ravl)函数,ravl是退出码








.线程的链接
int pthread_join(pthread_t tid,void *rval)
功能:调用该函数的线程会一直阻塞,知道指定的线程tid调用pthread_exit从启动例程返回或者被取消
参数一:就是指定线程的tid
参数二:是指定线程的返回码,如果线程被取消,那么rval被置为PTHREAD_CANCELED
返回值:成功返回0,失败返回错误码
注意:一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。
注意:调用pthread_join会使指定的线程已经处于分离状态,如果指定的线程已经处于分离状态,那么调用会失败。pthread_detach可以分离一个线程,线程自己可以分离自己
int pthread_detach(pthread_t thread)
成功返回0,失败返回错误码
   






.互斥量
(
)功能:为了让线程访问数据不冲突,这就需要对变量进行加锁,使得统一时刻只有一个线程可以访问变量。互斥量本质就是锁,访问共享资源前对互斥量加锁,访问完成后解锁。当互斥量加锁后,其他所有需要访问该互斥量的线程都将被阻塞。当互斥量解锁以后,所有因为这个互斥量阻塞的线程都将变为就绪态,第一个获得cpu的线程会获得互斥量,变为运行态,而其他需要访问该互斥量的线程会继续被阻塞,在这种方式下访问互斥量每次只有一个进程能够执行。
(
)类型:pthread_mutex_t
注意:在使用互斥量之前需要对互斥量进行初始化
1.
如果是动态分配的互斥量,可以调用pthread_mutex_init()函数初始化
2.
如果是静态分配的互斥量,还可以把它置为常量PTHREAD_MUTEX_INITIALIZER
   
例子:pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER
3.
动态分配的互斥量在释放内存之前需要调用pthread_mutex_destroy()
4.int pthread_mutex_init(pthread_mutex_t *restrict mutex,constpthread_mutexattr_t *restrict attr)
第一个参数:要初始化的互斥量
第二个参数:互斥量的属性,默认为NULL
5.int pthread_mutex_destroy(pthread_mutex_t *mutex)
(
)互斥量的加锁:
1.int pthread_mutex_lock(pthread_mutex_t *mutex)
返回值:成功返回0,失败返回错误码
注意:如果互斥量已经被锁住,那么会导致该线程阻塞
2.int pthread_mutex_trylock(pthread_mutex_t *mutex)
返回值:如果成功返回0,失败返回错误码
注意:如果互斥量已经被锁住,不会导致线程阻塞
(
)互斥量的解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex)
返回值:成功返回0,失败返回错误码





.读写锁
(
)读写锁与互斥量类似,不过读写锁有更高的并行性。互斥量要么加锁要么不加锁,而且同一时刻只允许一个线程对其加锁,对于一个变量的读取,完全可以让多个线程同时进行操作
(
)类型:pthread_rwlock_trwlock
1.
读写锁有三种状态,读模式下加锁,不加锁,写模式下加锁。一次只有一个线程可以占有写模式下的读写锁,但是多个线程可以同时占有读模式的读写锁。
2.
读写锁在写加锁状态时,在它被解锁之前,所有试图对这个锁加锁的线程都会阻塞。读写锁在读加锁状态时,所有试图以读模式对其加锁的线程都会获得访问权,但是如果线程希望以写模式对其加锁,它必须阻塞希望对它进行写加锁的线程,直到所有线程中的读加锁被释放
3.
当读写锁以读模式加锁时,如果有线程试图以写模式对其加锁,那么读写锁会阻塞随后的读模式锁请求。这样可以避免读锁长期占用,而写锁达不到请求。
4.
读写锁非常适合对数据结构读次数大于写次数的程序,当它以读模式锁住时,是以共享的方式锁住的。当它以写模式锁住时,是以独占的方式锁住的
(
)在使用读写锁之前需要对其进行初始化
1.int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,constpthread_rwlockattr_t *restrict attr)
第一个参数:要初始化的读写锁
第二个参数:属性
使用完之后要对读写锁进行销毁:
2.int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
返回值:成功返回0,失败返回错误码
(
)读模式的加锁
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
(
)写模式的加锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
(
)解锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)







.条件变量
类型:pthread_cond_t cond
注意:条件变量使用之前需要初始化
(
)初始化
1.
静态初始化pthread_cond_tcond=PTHREAD_COND_INITIALIZER
2.
动态初始化int pthread_cond_init(pthread_cond_t *restrictcond,const pthread_condattr_t *restrict attr)
条件变量使用完成后需要销毁:
int pthread_cond_destroy(pthread_cond_t *cond)
(
)条件变量的使用需要配合互斥量:
1.int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrictmutex)
使用pthread_cond_wait等待条件变为真。传递给pthread_cond_wait的互斥量对条件进行保护,调用者把锁住的互斥量传递给函数
这个函数将线程放在等待条件的线程列表上,然后对互斥量进行解锁,这是个原子操作。当条件满足时这个函数返回,返回以后对互斥量加锁
2.int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t*restrict mutex,const struct timespec *restrict abstime)
这个函数与pthread_cond_wait类似,只是多一个timeout,如果到了指定的时间条件还不满足,那么就返回。时间用下面的结构体表示
struct timespec
{
    time_t tv_sec;
    long tv_nsec;
}
注意:这个时间时绝对时间。例如你要等待三分钟,就要把当前时间加上三分钟然后转换到timespec,而不是直接将三分钟转换到timespec
(
三)当条件满足时,需要唤醒等待的线程
int pthread_cond_broadcast(pthread_cond_t *cond)
int pthread_cond_signal(pthread_cond_t *cond)
1.pthread_cond_broadcast
唤醒等待条件的所有线程
2.pthread_cond_signal
唤醒等待条件的某一线程
注意:一定要在条件改变以后再唤醒线程
例子:
void *fun(void *arg)
{
    pthread_mutex_lock(p->lock);
    if(p->readpos==writepos)
    {
        printf("consumer wait for notempty\n");
        pthread_cond_wait(&p->notempty,&p->lock);
    }
    data=p->buffer[p->readpos];
    pthread_mutex_unlock(p->lock);
}
上面条件的意思是当p->readpos==writepos时,等待另一个进程发送&p-notempty信号过来时,该进程才可以继续往下执行,要不然一直等待






.一次性初始化
有些事需要且只能执行一次,比如互斥量初始化。通常当初始化应用程序时,可以比较容易地将其放在main()函数中。但当你写一个库函数时,就不能在main里面初始化了,你可以用静态初始化,但使用一次初始(pthread_once_t)会比较容易些。
首先要定义一个pthread_once_tonce_control=PTHREAD_ONCE_INIT;
void init_routine()
{
    //
初始化互斥量
    //
初始化读写锁
}
接下来就可以在任何时刻调用pthread_once函数
int pthread_once(pthread_once_t *once_control,void (*init_routine)(void))
功能:本函数使用初值为PTHREAD_ONCE_INITonce_control变量保证init_routine()函数在本进程执行序列中仅执行一次。在多线程编程环境下,尽管pthread_once()调用会出现在多个线程中,init_routine()函数仅执行一次,究竟在哪个线程中执行是不一定的,是由内核的调度来决定的。
linux Threads
使用互斥锁和条件变量保证由pthread_once()指定的函数执行且执行一次。实际"一次性函数"的执行状态有三种:NEVER0)、IN_PROGRESS1)、DONE2,once_control来表示pthread_once()的执行状态
1.
如果once_control初值为0,那么pthread_once从未执行过,init_routine()函数会执行
2.
如果once_control初值设为1,代表pthread_once()正在执行,因此所有的pthread_once()都会陷入永久的等待中,init_routine()就无法执行
3.
如果once_control设为2,则表示pthread_once()函数已执行过一次,从而所有pthread_once()都会立即返回,init_routine()就没有机会执行
pthread_once函数成功返回,once_control就会被设置为2。并且在初始化时可以把once_control设为0.1.2







.线程属性
(
)创建线程函数:intpthread_create(pthread_t *restrict,const pthread_attr_t *restrict attr,void*(*start_routine)(void *),void *restrict arg)
1.
线程属性用pthread_attr_t类型的结构表示,在创建线程的时候可以不用传入NULL,而是传入一个pthread_attr_t结构,由用户自己来配置线程的属性
2.pthread_attr_t
类型对应用程序是不透明的,也就是说应用程序不需要了解有关属性对象内部结构的任何细节,因而可以增加程序的可移植性
(
)介绍几种线程属性如下:
detachstate:
线程的分离状态
guardsize:
线程栈末尾的警戒区域大小(字节数)
stacksize:
线程栈的最低字节
stacksize:
线程栈的大小(字节数)
注意:并不是所有的系统都支持线程的这些属性,因此你需要检查当前系统是否支持你设置的属性。当然还有一些属性不包含在pthread_attr_t结构中,例如:线程的可取消状态,取消类型,并发度
(
)pthread_attr_t结构在使用之前需要初始化,使用完之后需要销毁
(
)线程属性的初始化
int pthread_attr_init(pthread_attr_t *attr)
(
)线程属性销毁
int pthread_attr_destroy(pthread_attr_t *attr)
如果在调用pthread_attr_init初始化属性的时候分配了内存空间,那么pthread_attr_destroy将释放内存空间。除此之外,pthread_attr_destroy还会用无效的值初始化pthread_attr_t对象,因此如果该属性对象被误用,会导致线程创建失败
(
)如果在创建线程的时候知道不需要知道线程的终止状态,那么可以修改pthread_attr_t结构体中的detachstate属性,让线程以分离状态启动。可以使用pthread_attr_setdetachstate函数来设置线程的分离状态属性。线程的分离属性有两种合法值:
1.PTHREAD_CREATE_DETACHED(
分离的)
2.PTHREAD_CREATE_JOINABLE(
非分离的,可链接的)
int pthread_attr_setdetachstate(pthread_attr_t *attr,int detachstate)(
设置分离属性)
int pthread_attr_getdetachstate(pthread_attr_t *attr,int *detachstate)(
获得线程的分离状态属性)
(
)设置线程分离属性的步骤
1.
定义线程属性变量pthread_attr_t attr
2.
初始化attr,pthread_attr_init(&attr)
3.
设置线程为分离值或非分离pthread_attr_setdetachstate(&attr,detachstate)
4.
创建线程pthread_create(&tid,&attr,thread_fun,NULL)
所有系统都会支持线程的分离状态属性
例子:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
pthread_create(&tid,&attr,thread_fun,,NULL);
pthread_attr_destroy(&attr);
(
)线程栈属性
1.
对于进程来说,虚拟地址空间的大小是固定的,进程中只有一个栈,因此它的大小通常不是问题。但对线程来说,同样的虚拟地址被所有的线程共享。如果应用程序使用了太多的线程,导致线程栈累计超过可用的虚拟地址空间,这个时候就需要减少线程默认的栈大小。另外,如果线程分配了大量的自动变量或者线程的栈帧太深,那么这个时候需要的栈要比默认的大。
2.
如果用完了虚拟地址空间,可以使用malloc或者mmap来为其他栈分配空间,并修改栈的位置。
(
)修改栈属性
int pthread_attr_setstack(pthread_attr_t *attr,void *stackaddr,size_tstacksize)
(
十一)获取栈属性:
int pthread_attr_getstack(pthread_attr_t *attr,void **stackaddr,size_t*stacksize)
注意:参数stackaddr是栈的内存单元最低地址,参数stacksize是栈的大小。你要注意stackaddr并不一定是栈的开始,对于一些处理器,栈的地址是从高往低的,那么stackaddr是栈的结尾。
(
十二)当然也可以单独获取或者修改栈的大小,而不去修改栈的地址。对于栈的大小设置,不能小于PTHREAD_STACK_MIN(需要头文件limit.h)
int pthread_attr_setstacksize(pthread_attr_t *attr,size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr,size_t *stacksize);
对于栈的大小设置,在创建线程后,还可以修改。
(
十三)对于遵循POSIX标准的系统来说,不一定支持线程的栈属性,因此你需要检查
1.
在编译阶段使用
_POSIX_THREAD_ATTR_STACKADDR
_POSIX_THREAD_ATTR_STACKSIZE符号来检查系统是否支持线程栈属性,这些宏定义在/usr/include/bits/posix_opt.h
2.
在运行阶段把
_SC_THREAD_ATTR_STACKADDR
_SC_THREAD_ATTR_STACKSIZE传递给sysconf函数检查系统对线程栈属性的支持
(
十四)线程属性guardsize控制着线程栈末尾以后用以避免栈溢出的扩展内存大小,这个属性默认是PAGESIZE个字节。你可以把它设为0,这样就不会提供警戒缓冲区。同样的,如果你修改了stackaddr系统会认为你自己要管理栈,警戒缓冲区会无效。
1.
设置guardsize:
int pthread_attr_setguardsize(pthread_attr_t *attr,size_t guardsize)
2.
获取guardsize:
int pthread_attr_getguardsize(pthread_attr_t *attr,size_t *guardsize)






.互斥量的属性
int pthread_mutex_init(pthread_mutex_t *restrict mutex,constpthread_mutexattr_t *restrict attr)
就像线程有属性一样,线程的同步互斥量也有属性,比较重要的是进程共享属性和类型属性。互斥量的属性用pthread_mutexattr_t类型的数据表示,当然在使用之前必须进行初始化,使用完成之后需要进行销毁
(
)互斥量初始化:
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
(
)互斥量属性销毁:
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
(
)进程共享属性:
PTHREAD_PROCESS_PRIVATE,
这个是默认值,同一个进程中的多个线程访问同一个同步对象
PTHREAD_PROCESS_SHARED,
这个属性可以使互斥量在多个进程中进行同步,如果互斥量在多进程的共享内存区域,那么具有这个属性的互斥量可以同步多进程
(
)设置互斥量进程共享属性:
int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,int pshared)
int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr,int*restrict pshared)
(
)进程共享属性需要检测系统是否支持,可以检测宏_POSIX_THREAD_PROCESS_SHARED
(
)1.互斥量类型:PTHREAD_MUTEX_NORMAL,PTHREAD_MUTEX_ERRORCHEK,PTHREAD_MUTEX_RECURSIVE,PTHREAD_MUTEX_DEFAULT
2.
设置互斥量的类型属性:
int pthread_mutexattr_settype(pthread_mutexattr_t *attr,int type)
int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr,int*restrict type)






十一.读写锁的属性
读写锁的属性设置和互斥量类似,只是读写锁只有一个属性,即共享属性
(
)读写锁属性初始化:
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
(
)设置读写锁属性:
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr,int pshared)
int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr,int*restrict pshared)






十二.条件变量的属性
(
)条件变量属性初始化:
int pthread_condattr_init(pthread_condattr_t *attr)
int pthread_condattr_destroy(pthread_condattr_t *attr)
(
)设置条件变量属性:
int pthread_condattr_setpshared(pthread_condattr_t *attr,int pshared)
int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr,int*restrict pshared)






十三.线程的私有数据
1.
应用程序设计中有必要提供一种变量,使得多个函数多个线程都可以访问这个变量(看起来是个全局变量),但是线程对这个变量的访问都不会彼此产生影响(貌似不是全局变量),但是你需要这样的数据,比如errno。那么这中数据就是线程的私有数据,尽管名字相同,但是每个线程访问的都是数据的副本。
2.
在使用私有数据之前,你首先要创建一个与私有数据相关的键,要来获取对私有数据的访问权限。这个键的类型是pthread_key_t
int pthread_key_create(pthread_key_t *key,void(*destructor)(void *))
创建的键放在key指向的内存单元,destructor是与键相关的析构函数。当线程调用pthread_exit或者使用return返回,析构函数就会被调用。当析构函数调用的时候,它只有一个参数,这个参数是与key关联的那个数据的地址(也就是你的私有数据),因此你可以在析构函数中将这个数据销毁。
3.
键使用完之后也可以销毁,当键销毁之后,与它关联的数据并没有销毁
int pthread_key_delete(pthread_key_t key)
4.
有了键之后,你就可以将私有数据和键关联起来,这样就可以通过键来找到数据。所有的线程都可以访问这个键,但他们可以为键关联不同的数据。(这和名字一样而值不同的全局变量一样)
将私有数据与键关联:
int pthread_setspecific(pthread_key_t key,const void *value)
获取私有数据的地址,如果没有数据与key关联,那么返回空
void *pthread_getspecific(pthread_key_t key)






十四.线程与fork()
1.
当线程调用fork函数时,就为子进程创建了整个进程地址空间的副本,子进程通过继承整个地址空间的副本,也会将父进程的互斥量、读写锁、条件变量的状态继承过来。也就是说,如果父进程中互斥量是锁着的,那么在子进程中互斥量也是锁着的(尽管子进程自己没来得及lock),这是非常不安全的,因为不是子进程自己锁住的,它无法解锁。
2.
子进程内部只有一个线程,由父进程中调用fork()函数的线程副本构成。如果调用fork的线程将互斥量锁住,那么子进程会拷贝一个pthread_mutex_lock副本,这样子进程就有机会去解锁了。或者互斥量根本就没被加锁,这样也是可以的,但是你不能确保永远都是这样的情况
3.pthread_atfock
函数给你创造了这样的条件,它会注册三个函数
    int pthread_atfork(void(*prepare)(vodi),void (*parent)(void),void (*child)(void))
    prepare
是在fork调用之前会被调用的,parentfork返回父进程之前调用,childfork返回子进程之前调用,如果在prepare中加锁所有的互斥量,在parent
        child
中解锁所有的互斥量,那么在fork返回之后,互斥量处于未加锁状态
4.
可以用多个pthread_atfork函数,这是也就会有多个处理程序(prepare,parent,child)。多个prepare的执行顺序与注册顺序相反,而parentchild的执行顺序与注册顺序相同


 

【基于QT的调色板】是一个使用Qt框架开发的色彩选择工具,类似于Windows操作系统中常见的颜色选取器。Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动和嵌入式设备,支持C++和QML语言。这个调色板功能提供了横竖两种渐变模式,用户可以方便地选取所需的颜色值。 在Qt中,调色板(QPalette)是一个关键的类,用于管理应用程序的视觉样式。QPalette包含了一系列的颜色角色,如背景色、前景色、文本色、高亮色等,这些颜色可以根据用户的系统设置或应用程序的需求进行定制。通过自定义QPalette,开发者可以创建具有独特视觉风格的应用程序。 该调色板功能可能使用了QColorDialog,这是一个标准的Qt对话框,允许用户选择颜色。QColorDialog提供了一种简单的方式来获取用户的颜色选择,通常包括一个调色板界面,用户可以通过滑动或点击来选择RGB、HSV或其他色彩模型中的颜色。 横渐变取色可能通过QGradient实现,QGradient允许开发者创建线性或径向的色彩渐变。线性渐变(QLinearGradient)沿直线从一个点到另一个点过渡颜色,而径向渐变(QRadialGradient)则以圆心为中心向外扩散颜色。在调色板中,用户可能可以通过滑动条或鼠标拖动来改变渐变的位置,从而选取不同位置的颜色。 竖渐变取色则可能是通过调整QGradient的方向来实现的,将原本水平的渐变方向改为垂直。这种设计可以提供另一种方式来探索颜色空间,使得选取颜色更为直观和便捷。 在【colorpanelhsb】这个文件名中,我们可以推测这是与HSB(色相、饱和度、亮度)色彩模型相关的代码或资源。HSB模型是另一种常见且直观的颜色表示方式,与RGB或CMYK模型不同,它以人的感知为基础,更容易理解。在这个调色板中,用户可能可以通过调整H、S、B三个参数来选取所需的颜色。 基于QT的调色板是一个利用Qt框架和其提供的色彩管理工具,如QPalette、QColorDialog、QGradient等,构建的交互式颜色选择组件。它不仅提供了横竖渐变的色彩选取方式,还可能支持HSB色彩模型,使得用户在开发图形用户界面时能更加灵活和精准地控制色彩。
标题基于Spring Boot的二手物品交易网站系统研究AI更换标题第1章引言阐述基于Spring Boot开发二手物品交易网站的研究背景、意义、现状及本文方法与创新点。1.1研究背景与意义介绍二手物品交易的市场需求和Spring Boot技术的适用性。1.2国内外研究现状概述当前二手物品交易网站的发展现状和趋势。1.3论文方法与创新点说明本文采用的研究方法和在系统设计中的创新之处。第2章相关理论与技术介绍开发二手物品交易网站所涉及的相关理论和关键技术。2.1Spring Boot框架解释Spring Boot的核心概念和主要特性。2.2数据库技术讨论适用的数据库技术及其在系统中的角色。2.3前端技术阐述与后端配合的前端技术及其在系统中的应用。第3章系统需求分析详细分析二手物品交易网站系统的功能需求和性能需求。3.1功能需求列举系统应实现的主要功能模块。3.2性能需求明确系统应满足的性能指标和安全性要求。第4章系统设计与实现具体描述基于Spring Boot的二手物品交易网站系统的设计和实现过程。4.1系统架构设计给出系统的整体架构设计和各模块间的交互方式。4.2数据库设计详细阐述数据库的结构设计和数据操作流程。4.3界面设计与实现介绍系统的界面设计和用户交互的实现细节。第5章系统测试与优化说明对系统进行测试的方法和性能优化的措施。5.1测试方法与步骤测试环境的搭建、测试数据的准备及测试流程。5.2测试结果分析对测试结果进行详细分析,验证系统是否满足需求。5.3性能优化措施提出针对系统性能瓶颈的优化建议和实施方案。第6章结论与展望总结研究成果,并展望未来可能的研究方向和改进空间。6.1研究结论概括本文基于Spring Boot开发二手物品交易网站的主要发现和成果。6.2展望与改进讨论未来可能的系统改进方向和新的功能拓展。
1. 用户与权限管理模块 角色管理: 学生:查看个人住宿信息、提交报修申请、查看卫生检查结果、请假外出登记 宿管人员:分配宿舍床位、处理报修申请、记录卫生检查结果、登记晚归情况 管理员:维护楼栋与房间信息、管理用户账号、统计住宿数据、发布宿舍通知 用户操作: 登录认证:对接学校统一身份认证(模拟实现,用学号 / 工号作为账号),支持密码重置 信息管理:学生完善个人信息(院系、专业、联系电话),管理员维护所有用户信息 权限控制:不同角色仅可见对应功能(如学生无法修改床位分配信息) 2. 宿舍信息管理模块 楼栋与房间管理: 楼栋信息:名称(如 "1 号宿舍楼")、层数、性别限制(男 / 女 / 混合)、管理员(宿管) 房间信息:房间号(如 "101")、户型(4 人间 / 6 人间)、床位数量、已住人数、可用状态 设施信息:记录房间内设施(如空调、热水器、桌椅)的配置与完好状态 床位管理: 床位编号:为每个床位设置唯一编号(如 "101-1" 表示 101 房间 1 号床) 状态标记:标记床位为 "空闲 / 已分配 / 维修中",支持批量查询空闲床位 历史记录:保存床位的分配变更记录(如从学生 A 调换到学生 B 的时间与原因) 3. 住宿分配与调整模块 住宿分配: 新生分配:管理员导入新生名单后,宿管可按专业集中、性别匹配等规则批量分配床位 手动分配:针对转专业、复学学生,宿管手动指定空闲床位并记录分配时间 分配结果公示:学生登录后可查看自己的宿舍信息(楼栋、房间号、床位号、室友列表) 调整管理: 调宿申请:学生提交调宿原因(如室友矛盾、身体原因),选择意向宿舍(需有空位) 审批流程:宿管审核申请,通过后执行床位调换,更新双方住宿信息 换宿记录:保存调宿历史(申请人、原床位、新床位、审批人、时间) 4. 报修与安全管理模块 报修管理: 报修提交:学生选择宿舍、设施类型(如 "
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值