并发 -------- 2.5进程间的通信 - 信号量

前言:进程间的通信方式包括


    IPC: 
        1、管道
            pipe 无名管道
            fifo 有名管道 
        2、信号 signal        
        3、消息队列 System V消息队列 / POSIX消息队列     
        4、共享内存 System V共享内存 / POSIX共享内存       
        5、信号量   System V信号量 / POSIX信号量            <-----------
        6、socket套接字


1、引入 

    例子: 
        int i = 0;

        func()
        {
            i++;
        }

        当有两个任务,调用func()函数时,执行之后i的值为多少? 
        答: 不确定的,因为i++ 是一个非原子操作  
                            可以分割成3个步骤: 
                                (1)读取 
                                (2)计算
                                (3)回写

            ====================
             ps.   原子操作 Atomic Operation 
                    一般定义为 在执行过程中不会被线程调度机制中断的操作
                    这种操作一旦开始 就会一直运行到结束,中间不会被其他的线程的操作所打断 
                    原子操作是不可分割的,即操作要么完全执行,要么完全不执行,不存在执行一半的情况

                     非原子操作与之相反

        
        综上所述如果有两个或者多个任务(进程/线程),去访问同一个共享资源(硬件/软件) 那么就必须要保证这个共享资源的 被有序访问。
            

2、信号量 semaphore

    信号量 
        是用于 不同进程之间 或者 同一个进程中不同线程之间 的同步机制  
            同步 ---> 有序、有条件的访问 

        信号量的出现,就是为了保护共享资源,让共享资源被有序的访问 

        信号量 是用来表示一种资源的数量 
                是一种特殊的计数器,用于控制对共享资源的访问 

        什么时候需要信号量? 
            需要保护对象的时候,就需要信号量 
            “保护”:让被保护的对象(共享资源)被有序访问 

    
3、如何保护? 

    信号量机制 其实是对程序设计者的约束,用来保护共享资源的

        例子: 
            进程A   进程B   都需要访问同一个“互斥”设备 

            那么就用一个信号量来表示能不能访问该设备,然后每一个进程在访问这个设备之前,
            都先去访问这个信号量: 
                如果能够访问该设备,就先将信号量调成“NO”,然后再去访问这个互斥设备,
                访问完之后,最后再将该信号量调成“YES”

    信号量如何实现? 
        一个进程(或线程)在某一个信号量上 执行3个操作: 

            (1)创建一个信号量,还必须要求 调用者指定信号量的初始值 
                初始值就表示给信号量保护的共享资源 可以被多少个任务访问 

                    sem --> 1  表示可以被1个进程或者线程去访问
                    sem --> 5  表示可以被5个进程或者线程去访问

            
            (2)等待一个信号量,该操作会测试这个信号量的值 
                如果其值小于或者等于0 那么就会阻塞(等待)
                一旦它的值变成大于0  就会先将它-1 在继续执行访问它的代码

                    while( sem_value <= 0 )
                    {
                        wait 
                    }
                    sem_value --;
                    访问 

                p操作 proberen (尝试 荷兰语)
                lock 上锁


            (3)释放一个信号量,将信号量的值+1 

                    sem_value ++;

                v操作 verhogen (增加)
                unlock 解锁


        信号量保护: 
            在临界区的前面 加上一个p操作,然后在临界区的后面 加上一个v操作 
                “临界区”: 把操作“共享资源”的代码区域 称为 临界区

                p 
                xxx     //临界区
                v 


4、信号量的实现 

    System V semaphore 

    POSIX semaphore 
            POSIX 有名 semaphore 
            POSIX 无名 semaphore 

    
    4.1)System V semaphore 

        System V 信号量  ---> 计数信号量集 (信号量数组) 
                                存在于 内核中 

            对于系统中的每个信号量集,内核都会维护在如下的结构体中:
                    

        
                struct semid_ds 
                {
                    struct ipc_perm sem_perm;  /* 权限 Ownership and permissions */
                    time_t          sem_otime; /* 最后调用semp()的时间 Last semop time */
                    time_t          sem_ctime; /* 最后修改的时间 Last change time */
                    unsigned long   sem_nsems; /* 信号量数组中有多少信号量 No. of semaphores in set */
                };

        接口函数: 
            (1)获取键值key 
                ftok() 

            (2)创建或者打开一个System V信号量集
                semget() 

                    NAME
                        semget - get a System V semaphore set identifier
                    SYNOPSIS
                        #include <sys/types.h>
                        #include <sys/ipc.h>
                        #include <sys/sem.h>

                        int semget(key_t key, int nsems, int semflg);
                            功能:创建或者打开一个System V信号量集
                            参数: 
                                key:键值 
                                nsems:指定要创建的信号量集中 信号量的个数
                                semflg: 标志位
                                        (1)创建标志 
                                            IPC_CREAT | 权限位 
                                            例子: 
                                                IPC_CREAT | 0666 
                                            注意: 
                                                如果创建失败的原因 是因为已经存在了
                                                且 创建的标志为 IPC_CREAT | IPC_EXCL 一起使用 
                                                此时 errno == EEXIST 
                                        (2)打开标志 
                                            0 
                            返回值: 
                                成功,返回该信号量集的id
                                失败,返回-1,同时errno被设置

                    
                    注意: 
                        在创建一个信号量集时,信号量的值是不确定的
                        因此 我们在创建一个信号量集之后,要马上指定它们的初始值 


            (3)控制操作 
                semctl 

                    NAME
                        semctl - System V semaphore control operations
                    SYNOPSIS
                        #include <sys/types.h>
                        #include <sys/ipc.h>
                        #include <sys/sem.h>

                        int semctl(int semid, int semnum, int cmd, ...);
                            功能:对System V信号量集的控制操作 
                            参数: 
                                semid: 信号量集id 
                                semnum:指定要操作哪个信号量,就是信号量数组的下标(0,1,2,...)
                                cmd: 命令号 
                                        IPC_RMID    删除 
                                        IPC_STAT    获取属性 
                                        IPC_SET     设置属性 
                                        GETVAL      获取某个信号量的值
                                        SETVAL      设置某个信号量的值 
                                        GETALL      获取所有信号量的值 
                                        SETALL      设置所有信号量的值
                                        ...
                                ...:第四个参数,根据cmd的不同,第四个参数也不相同
                                        第四个参数的类型: 
                                            union semun 
                                            {
                                                int              val;    /* Value for SETVAL */
                                                struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
                                                unsigned short  *array;  /* Array for GETALL, SETALL */
                                                struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
                                            };

               

              //设置信号量数组中的第一个元素的初始值
                    union semun  a;
                    a.val = 2;
                    semctl( sem_id, 0, SETVAL, a.val );

                    =============================
                        如果 cmd == IPC_RMID 删除信号量集  
                            第四个参数就不要了 

                    =============================
                        如果 cmd == GETVAL      获取某个信号量的值,第四个参数也不要
                                            函数的返回值 就是该信号量的值 
                                            例子: 
                                                int b = semctl( sem_id, 0, GETVAL );

                    =============================
                        如果 cmd == SETVAL      设置某个信号量的值,第四个参数为int类型
                                            例子: 
                                                设置信号量集中第二个的信号量的值为10 
                                                int a = 10;
                                                semctl( sem_id, 1, SETVAL, a );

                    ==============================
                        如果 cmd == GETALL      获取整个信号量集中的  所有信号量的值 
                                                第四个参数的类型为 unsigned short [] 
                                                    用来存放所获取到的信号量集的值 
                                                例子: 
                                                    unsigned short arr[6];
                                                    semctl( sem_id, 0, GETALL, arr );

                    ==============================
                        如果 cmd == SETALL      设置整个信号量中的 所有信号量的值 
                                                第四个参数的类型为 unsigned short [] 
                                                    用来存放要设置的信号量集的值
                                                例子: 
                                                    unsigned short arr[6] = {1,1,0,2,3,4};
                                                    semctl( sem_id, 0, SETALL, arr ); 
                        练习: 
                            创建一个System V信号量集 (5个)
                            并 给这个信号量集设置初始值, 并 获取第三个信号量的值并打印 

                            #define PATHNAME "/home/china/"

                            int main()
                            {
                                //1.获取键值key 
                                key_t  key = ftok( PATHNAME, 7 );
                                if( key == -1 )
                                {
                                    perror("ftok error ");
                                    return -1;
                                }
                                printf("key = 0x%x\n", key );

                                //2.创建或打开一个信号量集 
                                int sem_id = semget( key, 5, IPC_CREAT | IPC_EXCL | 0666 );
                                if( sem_id == -1 )
                                {
                                    if( errno == EEXIST )   //已经存在,就直接打开 
                                    {
                                        sem_id = semget( key, 5, 0 );
                                    }
                                    else 
                                    {
                                        perror("semget error ");
                                        return -1;
                                    }
                                }
                                printf("sem_id = %d\n", sem_id );

                                //3.控制操作 
                                    //设置初始值 SETALL
                                    unsigned short arr[5] = {0,2,4,6,8};
                                    semctl( sem_id, 0, SETALL, arr );

                                    //获取第三个信号量的值并打印  GETVAL
                                    int x = semctl( sem_id, 2, GETVAL );
                                    printf("x = %d\n", x );

                                    for( int i=0; i<5; i++ )
                                    {
                                        printf("%d  ", semctl( sem_id, i, GETVAL ) );
                                    }
                                    putchar('\n');
                            }


            (4.1.2)信号量p/v操作 


                semop() 

                    NAME
                        semop - System V semaphore operations

                    SYNOPSIS
                        #include <sys/types.h>
                        #include <sys/ipc.h>
                        #include <sys/sem.h>

                        int semop(int semid, struct sembuf *sops, size_t nsops);
                            功能:对System V信号量集的p/v操作 
                            参数: 
                                semid: 信号量集id 
                                sops:结构体指针,信号量p/v操作的结构体数组 
                                        可能同时对多个信号量进行操作 
                                    在System V信号量集中,对某个信号量的操作 用结构体来描述的
                                        struct sembuf 
                                        {
                                            unsigned short sem_num;  /* 指定要操作的信号量(信号量数组的下标) semaphore number */
                                            short          sem_op;   /* 操作 semaphore operation */
                                                                        sem_value = 原来sem_value + sem_op;

                                                                            sem_op < 0  --->  - p操作 
                                                                            sem_op > 0  --->  + v操作 
                                                                            sem_op == 0 --->  如果sem_value==0 立即返回 
                                                                                            如果sem_value!=0  看阻塞还是非阻塞 

                                            short          sem_flg;  /* 操作标志 operation flags */
                                                                    0   阻塞 
                                                                    IPC_NOWAIT  非阻塞  
                                                                    SEM_UNDO    撤销 ,为了防止进程“带锁退出” 
                                                                                    如果设置了SEM_UNDO 那么在进程退出时 
                                                                                    内核会自动释放该进程持有的信号量 

                                        }
                                nsops:第二个参数 需要操作的信号量的个数 
                                        表示你要对多少个信号量进行操作 
                            返回值: 
                                成功,返回0 
                                失败,返回-1,同时errno被设置 

                例子: 
                    // p操作 上锁 
                    struct sembuf  buf;
                    buf.sem_num = 0;    //指定要操作的信号量(信号量数组的下标)
                    buf.sem_op = -1;    //-1  p操作 
                    buf.sem_flg = 0;    //阻塞 
                    semop( sem_id, &buf, 1 );

                    //临界区 (对共享资源的访问)
                    //...

                    // v操作 解锁 
                    buf.sem_num = 0;    //指定要操作的信号量(信号量数组的下标)
                    buf.sem_op = +1;    //+1  v操作 
                    buf.sem_flg = 0;    //阻塞 
                    semop( sem_id, &buf, 1 );
       

                        练习: 
                            创建一个System V信号量集 (5个)
                            并 给这个信号量集设置初始值, 并 获取第三个信号量的值并打印 

                            #define PATHNAME "/home/china/"

                            int main()
                            {
                                //1.获取键值key 
                                key_t  key = ftok( PATHNAME, 7 );
                                if( key == -1 )
                                {
                                    perror("ftok error ");
                                    return -1;
                                }
                                printf("key = 0x%x\n", key );

                                //2.创建或打开一个信号量集 
                                int sem_id = semget( key, 5, IPC_CREAT | IPC_EXCL | 0666 );
                                if( sem_id == -1 )
                                {
                                    if( errno == EEXIST )   //已经存在,就直接打开 
                                    {
                                        sem_id = semget( key, 5, 0 );
                                    }
                                    else 
                                    {
                                        perror("semget error ");
                                        return -1;
                                    }
                                }
                                printf("sem_id = %d\n", sem_id );

                                //3.控制操作 
                                    //设置初始值 SETALL
                                    unsigned short arr[5] = {0,2,4,6,8};
                                    semctl( sem_id, 0, SETALL, arr );

                                    //获取第三个信号量的值并打印  GETVAL
                                    int x = semctl( sem_id, 2, GETVAL );
                                    printf("x = %d\n", x );

                                    for( int i=0; i<5; i++ )
                                    {
                                        printf("%d  ", semctl( sem_id, i, GETVAL ) );
                                    }
                                    putchar('\n');
                            }

    4.2)POSIX semaphore   ----> 单个信号量 

        POSIX 有名信号量 
                可以用于任意的进程之间 或者 任意的线程之间 
                在文件系统中有一个名字(入口), 但是 信号量的值存在于内核中

        POSIX 无名信号量 
                线程 和 子进程之间  
                没有名字,基于内存的信号量 

                如果这段空间 在“内核中的共享内存中”, 进程可以访问,线程也可以访问
                如果这段空间 在“进程的地址空间中”, 只能用于该进程内部所有的线程的同步


       (4.2.1) 接口函数: 


            (1)创建或者打开一个POSIX信号量 
                POSIX信号量 用类型 sem_t 来表示 

                (1.1)创建并初始化一个POSIX有名信号量 
                    sem_open() 

                        NAME
                            sem_open - initialize and open a named semaphore

                        SYNOPSIS
                            #include <fcntl.h>           /* For O_* constants */
                            #include <sys/stat.h>        /* For mode constants */
                            #include <semaphore.h>

                            sem_t *sem_open(const char *name, int oflag);
                            sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);
                                功能:创建并初始化一个POSIX有名信号量 
                                参数: 
                                    name: 指定要创建或者打开的POSIX有名信号量的在文件系统中的路径名 
                                            以 / 开头的路径名  (实际生成在 /dev/shm/ 目录下) 
                                            例如: 
                                                "/data"     读信号量 
                                                "/space"    写信号量
                                    oflag:标志位 
                                            (1)创建标志  
                                                O_CREAT  
                                                要判断文件是否存在 O_CREAT | O_EXCL 
                                            (2)打开标志 
                                                0 
                                    mode:权限  
                                            (1)宏 
                                                S_IRUSR  S_IWUSR  S_IXUSR  S_IRGRP  S_IWGRP  S_IXGRP  S_IROTH  S_IWOTH  S_IXOTH 
                                            (2)八进制 
                                                0666 
                                    value:指定该信号量的初始值
                                返回值: 
                                    成功,返回 sem_t* 指针, 指向了一个已经打开的POSIX有名信号量 
                                    失败,返回 SEM_FAILED 指针,同时errno被设置 

                            
                            注意: 
                                Link with -pthread.
                                编译时 要链接库 -pthread         // pthread  ---> posix thread 

                        例子: 
                            sem_t * space = sem_open( "/space", O_CREAT | O_EXCL, 0666, 1 );
                            if( space == SEM_FAILED )
                            {
                                if( errno == EEXIST )   //已经存在,就直接打开 
                                {
                                    space = sem_open( "/space", 0 );
                                }
                                else
                                {
                                    perror("sem_open space error ");
                                    return -1;
                                }
                            }


                (4.2.2)初始化一个POSIX无名信号量 


                    sem_init() 
                            
                            初始化一个POSIX无名信号量,需要实现分配一个sem_t的空间
                             sem_t  st;  或者 sem_t * st = malloc( sizeof(sem_t) );

                        NAME
                            sem_init - initialize an unnamed semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_init(sem_t *sem, int pshared, unsigned int value);
                                功能:初始化一个POSIX无名信号量 
                                参数: 
                                    sem:要初始的POSIX无名信号量的地址
                                    pshared:指定该无名信号量的共享方式 
                                            0       进程内部的线程之间的访问
                                            1(非0)  不同的进程直接的访问  
                                                        如果是1这个情况,要保证sem指向的空间是不同进程都可以访问的
                                                        ---》 sem指向的空间,只能是共享内存 
                                    value:指定该信号量的初始值
                                返回值 :
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 


                  ps.        注意在编译时需要 加上  -pthread 使其与库连接


            (4.2.3)POSIX信号量的p/v操作 

                (2.1) p操作 
                    sem_wait() 
 
                        NAME
                            sem_wait, sem_timedwait, sem_trywait - lock a semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_wait(sem_t *sem);
                                功能:用来获取sem指定的信号量,一直阻塞等待,直到申请到资源
                                参数: 
                                    sem:指定要操作的信号量
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 


                            int sem_trywait(sem_t *sem);      //非阻塞 
                                功能:尝试获取sem指定的信号量,如果资源可用,立即返回,否则返回错误
                                        能获取则获取(返回0),不能获取则立即返回(返回-1)
                                

                            int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
                                功能:用来获取sem指定的信号量,限时等待 
                                参数: 
                                     sem:指定要操作的信号量
                                     abs_timeout:绝对时间 
                                                获取当前的时间(距离1970年1月1日00:00:00的秒数) + 愿意等待的时间 
                                                    struct timespec
                                                    {
                                                        time_t    tv_sec;    /* 秒 seconds */
                                                        long      tv_nsec;   /* 纳秒 nanoseconds */
                                                    };
                                                    1s == 1000ms == 1000000us == 1000000000ns 

                                                ==============================
                                          ps.          clock_gettime() 获取当前时间 

                                                        NAME
                                                            clock_gettime - clock and time functions
                                                        SYNOPSIS
                                                            #include <time.h>
                                                            int clock_gettime(clockid_t clk_id, struct timespec *tp);
                                                                功能:获取当前时间
                                                                参数: 
                                                                    clk_id:指定要获取的时间源  CLOCK_REALTIME  
                                                                    tp:指向一个timespec结构体的指针,用来存放时间 
                                                                返回值: 
                                                                    成功,返回0 
                                                                    失败,返回-1,同时errno被设置 
                     

  例子: 
                            愿意等待5秒40毫秒 

                            //获取当前时间
                            struct timespec ts; 
                            clock_gettime( CLOCK_REALTIME, &ts );

                            //当前时间 + 愿意等待的时间
                            ts.tv_sec += 5;
                            ts.tv_nsec += 40000000;
                            if( ts.tv_nsec >= 1000000000 )  //进位 
                            {
                                ts.tv_sec ++;
                                ts.tv_nsec -= 1000000000;
                            }


                            
                (2.2) v操作 
                    sem_post() 

                        NAME
                            sem_post - unlock a semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_post(sem_t *sem);
                                功能:释放sem指定的信号量, 即 对指定的信号量 进行 v操作 
                                参数: 
                                    sem:指定要操作的信号量
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 

                


                (4.2.4)用来获取信号量的值 


                    sem_getvalue() 

                        NAME
                            sem_getvalue - get the value of a semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_getvalue(sem_t *sem, int *sval);
                                功能:用来获取指定信号量的值 
                                参数: 
                                    sem:指定要操作的信号量
                                    sval:指针,指向的空间用来存放信号量的值 
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 

                
                (4.2.5)POSIX有名信号量的 关闭和删除操作 
                    


                    关闭 sem_close()  

                        NAME
                            sem_close - close a named semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_close(sem_t *sem);
                                功能:关闭一个POSIX有名信号量 
                                参数: 
                                    sem:指定要关闭的POSIX有名信号量
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 


                    删除 sem_unlink()  (尽量把之前创建的信号量删除)
                        
                        NAME
                            sem_unlink - remove a named semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_unlink(const char *name);
                                功能:删除一个POSIX有名信号量 
                                参数: 
                                    name:指定要删除的POSIX有名信号量的在文件系统中的路径名 
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 

                
                (4.2.6)POSIX 无名信号量的销毁 


                    sem_destroy() 

                        NAME
                            sem_destroy - destroy an unnamed semaphore
                        SYNOPSIS
                            #include <semaphore.h>

                            int sem_destroy(sem_t *sem);
                                功能:销毁一个POSIX无名信号量 
                                参数: 
                                    sem:指定要销毁的POSIX无名信号量
                                返回值: 
                                    成功,返回0 
                                    失败,返回-1,同时errno被设置 


       

 练习: 
            把 之前的练习题 改用 POSIX有名信号量 进行保护 

            posix_sem1.c  循环的依次写字符串s的每一个字符 到共享内存中,每次写一个
            posix_sem2.c   不断地从共享内存中去读取一个字符 并 打印 

                int main()
                {
                    //1.获取键值key -- 共享内存
                    key_t  key1 = ftok( PATHNAME, 5 );
                    if( key1 == -1 )
                    {
                        perror("ftok error ");
                        return -1;
                    }

                    //2.创建或打开一个共享内存
                    int shm_id = shmget( key1, 4096, IPC_CREAT | IPC_EXCL | 0666 );
                    if( shm_id == -1 )
                    {
                        if( errno == EEXIST )   //已经存在,就直接打开 
                        {
                            shm_id = shmget( key1, 0, 0 );
                        }
                        else 
                        {
                            perror("shmget error ");
                            return -1;
                        }
                    }

                    //3.映射  
                    char *p = shmat( shm_id, NULL, 0 );
                    if( p == NULL )
                    {
                        perror("shmat error ");
                        return -1;
                    }    


                    //======使用POSIX信号量 对共享资源 进行保护 ==========

                    sem_unlink( "/space" );    //只需要在写这边 删除一次 
                    sem_unlink( "/data" );

                    //读 data --> 0 
                        sem_t * data = sem_open( "/data", O_CREAT | O_EXCL, 0666, 0 );
                        if( data == SEM_FAILED )
                        {
                            if( errno == EEXIST )   //已经存在,就直接打开 
                            {
                                data = sem_open( "/data", 0 );
                            }
                            else
                            {
                                perror("sem_open data error ");
                                return -1;
                            }
                        }

                    //写 space --> 1 
                        sem_t * space = sem_open( "/space", O_CREAT | O_EXCL, 0666, 1 );
                        if( space == SEM_FAILED )
                        {
                            if( errno == EEXIST )   //已经存在,就直接打开 
                            {
                                space = sem_open( "/space", 0 );
                            }
                            else
                            {
                                perror("sem_open space error ");
                                return -1;
                            }
                        }

                    char *s = "1234567890";
                    int i = 0;
                    while(1)
                    {
                        // p操作 写 
                        sem_wait( space );

                        //临界区 
                            //4.写一个字符到共享内存 
                            *p = *( s + i );        //s[i]
                            i = ( i+1 ) % 10;        //循环写 

                        // v操作 读 
                        sem_post( data );
                    }

                    //5.解除映射 
                    shmdt( p );
                }

Matlab基于粒子群优化算法及鲁棒MPPT控制器提高光伏并网的效率内容概要:本文围绕Matlab在电力系统优化与控制领域的应用展开,重点介绍了基于粒子群优化算法(PSO)和鲁棒MPPT控制器提升光伏并网效率的技术方案。通过Matlab代码实现,结合智能优化算法与先进控制策略,对光伏发电系统的最大功率点跟踪进行优化,有效提高了系统在不同光照条件下的能量转换效率和并网稳定性。同时,文档还涵盖了多种电力系统应用场景,如微电网调度、储能配置、鲁棒控制等,展示了Matlab在科研复现与工程仿真中的强大能力。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的高校研究生、科研人员及从事新能源系统开发的工程师;尤其适合关注光伏并网技术、智能优化算法应用与MPPT控制策略研究的专业人士。; 使用场景及目标:①利用粒子群算法优化光伏系统MPPT控制器参数,提升动态响应速度与稳态精度;②研究鲁棒控制策略在光伏并网系统中的抗干扰能力;③复现已发表的高水平论文(如EI、SCI)中的仿真案例,支撑科研项目与学术写作。; 阅读建议:建议结合文中提供的Matlab代码与Simulink模型进行实践操作,重点关注算法实现细节与系统参数设置,同时参考链接中的完整资源下载以获取更多复现实例,加深对优化算法与控制系统设计的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值