当前位置: 首页 > news >正文

网站优化怎样的校园网站素材

网站优化怎样的,校园网站素材,网站建设硬件设置,58网页版登录打开线程间的通信即多个线程间传递信息。1.线程间通信方式线程间通信采取全局变量的方式,全局变量存放在数据区中,进程是操作系统资源分配的最小单元,每个进程空间独立,一个进程里所有线程共享数据段。需要注意的是:多线程…

线程间的通信即多个线程间传递信息。

1.线程间通信方式

        线程间通信采取全局变量的方式,全局变量存放在数据区中,进程是操作系统资源分配的最小单元,每个进程空间独立,一个进程里所有线程共享数据段。

                                        

需要注意的是:多线程同时操作共享空间会引发资源竞争,需要加上互斥锁解决资源竞争问题。

2.互斥锁(无法同步)

        解决资源竞争的一种方式,可以看成是一种资源只能加锁一次,加锁期间不能再次加锁,也不能强制占有一个已经加锁的锁资源,必须等待锁 资源释放,也就是解锁后才能继续操作该锁,加锁和解锁中间的代码称为临界代码,也称为临界区,互斥锁只能防止多个线程对资源的竞争,不能决定代码的先后执行顺序。

                        

2.1互斥锁使用方式

        1. 定义互斥锁(全局变量) 2. 对锁初始化 3. 操作全局资源前先加锁 4. 如果加锁成功则完成对全局资源操作 5. 如果加锁失败则表示有人占用资源,必须等待其余人释放锁资源才能加锁成功 6. 直到加锁成功使用该全局资源。

2.2互斥锁的函数接口

2.2.1pthread_mutex_init初始化互斥锁

原型:int pthread_mutex_init(pthread_mutex_t *restrict mutex, const 
pthread_mutexattr_t *restrict attr);
功能:
初始化互斥锁
参数:mutex:互斥锁空间首地址
attr:属性,默认为NULL
返回值:
成功返回0 
失败返回-1

2.2.2pthread_mutex_lock互斥锁加锁

原型:int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:
互斥锁加锁

2.2.3pthread_mutex_unlock互斥锁解锁

原型:int pthread_mutex_unlock(pthread_mutex_t *mutex);
功能:
互斥锁解锁

2.2.4pthread_mutex_destroy互斥锁销毁

原型:int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:
互斥锁销毁

下来使用一下互斥锁:

        互斥锁只能避免资源争抢,不能指定某个线程使用,由于没有延时,哪个线程能抢到锁取决于系统调度。

        先不使用互斥锁,不给进程上锁,会出现资源争抢的情况,进程1运行到num1 = value时进程可能会切换到进程2执行,出现了num1不等于num2的情况。

#include "head.h"
int num1 = 0;
int num2 = 0;
int value = 0;
pthread_mutex_t lock;
void *thread1(void *arg)
{while (1){//pthread_mutex_lock(&lock);//上锁num1 = value;num2 = value;value++;//pthread_mutex_unlock(&lock);//解锁}return NULL;
}
void *thread2(void *arg)
{while (1){//pthread_mutex_lock(&lock);//上锁if(num1 != num2){printf("num1 = %d num2 = %d\n", num1,num2);}//pthread_mutex_unlock(&lock);//解锁}return NULL;
}
int main(void)
{pthread_t tid1;pthread_t tid2;pthread_mutex_init(&lock, NULL);//初始化互斥锁pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_mutex_destroy(&lock);//销毁互斥锁return 0;
}

运行后会出现下面的情况

不难发现,在没有上锁的时候出现了num1=num2的情况,并且它还被打印了出来:

        这是由于num1和num2的赋值操作不是原子的,num1 = value和num2 = value看似两个独立操作,但在多线程环境下由于cpu指令重排和线程调度,他们可能会被拆分成多个机器指令,导致thread2观察到的状态出现错误,即可能会出现num1 !=num2的情况,也会出现thread2观察到num1 !=num2,但实际二者相等的情况。

再试试上锁,上锁完发现不会出现num1不等于num2的情况了。

#include "head.h"
int num1 = 0;
int num2 = 0;
int value = 0;
pthread_mutex_t lock;
void *thread1(void *arg)
{while (1){pthread_mutex_lock(&lock);//上锁num1 = value;num2 = value;value++;pthread_mutex_unlock(&lock);//解锁}return NULL;
}
void *thread2(void *arg)
{while (1){pthread_mutex_lock(&lock);//上锁if(num1 != num2){printf("num1 = %d num2 = %d\n", num1,num2);}pthread_mutex_unlock(&lock);//解锁}return NULL;
}
int main(void)
{pthread_t tid1;pthread_t tid2;pthread_mutex_init(&lock, NULL);//初始化互斥锁pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_mutex_destroy(&lock);//销毁互斥锁return 0;
}

3.死锁

        多线程由于加锁解锁错误导致程序无法继续向下运行的状态称为死锁状态,简称为死锁。

        死锁产生的四个必要条件:

必要条件解释如何破坏
互斥资源独占使用共享锁(如读写锁)
不可剥夺资源不能强行抢走允许系统强制回收
请求保持占用资源的同时申请新资源一次性申请所有资源
循环等待线程间形成等待环

按固定顺序加锁

        只要破坏一个条件即可避免死锁!

        避免死锁,应该使加锁顺序保持一致或使用pthread_mutex_trylock()非阻塞,立即返回替换pthread_mutex_lock(阻塞,直到获取锁)。

4.信号量(可以同步)

        信号量是一种资源,只能完成四种操作:初始化、销毁、申请、释放,如果信号量资源数为0,申请资源会阻塞等待,直到占用资源的任务释放资源,资源数不为0时,才能申请到资源并继续向下执行,释放资源不会阻塞。它可以做到互斥锁不能做到的同步功能。

​​​​​​​4.1信号量的函数接口

4.1.1sem_init初始化信号量

原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:
初始化信号量
参数:
sem:信号的空间的首地址
pshared:0:一个进程的多个线程间共享
非0:多个进程间共享
value:
初始化的资源的值
返回值:
成功返回0 
失败返回-1

4.1.2sem_destroy销毁信号量

原型:int sem_destroy(sem_t *sem);
功能:销毁信号量
参数:sem:信号量空间的首地址
返回值:成功返回0 失败返回-1 

4.1.3sem_wait申请信号量

        申请信号量会让信号量资源数-1, 如果信号量资源数为0,则会阻塞等待,直到有任务释放资源,才能拿到资源并继续向下 执行。

原型:int sem_wait(sem_t *sem);
功能:申请信号量
参数:sem:信号量空间首地址
返回值:成功返回0 失败返回-1 

4.1.4sem_post释放信号量

原型:int sem_post(sem_t *sem);
功能:释放信号量
参数:sem:信号量空间首地址
返回值:成功返回0 失败返回-1

应用示例:建立三个线程,将ABC依次打印出来。

#include "head.h"
sem_t sem_PA;
sem_t sem_PB;
sem_t sem_PC;
void *thread1(void *arg)
{while (1){sem_wait(&sem_PA);printf("A");sem_post(&sem_PB);}return NULL;
}
void *thread2(void *arg)
{while (1){sem_wait(&sem_PB);printf("B");sem_post(&sem_PC);}return NULL;
}
void *thread3(void *arg)
{while (1){sem_wait(&sem_PC);printf("C");sem_post(&sem_PA);}return NULL;
}
int main(void)
{sem_init(&sem_PA, 0, 1);sem_init(&sem_PB, 0, 0);sem_init(&sem_PC, 0, 0);pthread_t tid1;pthread_t tid2;pthread_t tid3;pthread_create(&tid1, NULL, thread1, NULL);pthread_create(&tid2, NULL, thread2, NULL);pthread_create(&tid2, NULL, thread3, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);pthread_join(tid3, NULL);sem_destroy(&sem_PA);sem_destroy(&sem_PB);sem_destroy(&sem_PC);return 0;
}

        ​​​​​​​                

                            显然,既没有出现资源抢夺现象,也完成了对线程的同步。

http://www.dtcms.com/a/429253.html

相关文章:

  • 先看网站案例您的网站也可以这么做国外手机设计网站
  • t购物网站开发前景吉林省最新消息今天新增
  • 网站开发软件和工具ide和编辑器哈尔滨手机网站建设价格低
  • lnmp 网站开发总结房产网上查询
  • 浅谈高校网站群的建设森东网站建设
  • 网站地址ip域名查询西宁集团网站建设
  • 网站开发所需的费用帮企业建设网站和维护
  • 短租网站开发全国企业系统网站建设
  • php企业网站开发价格做网站卖赚钱吗
  • 网站开发攻克时间网站改版 权重
  • 手机网站端域名怎样做解析房山 网站建设
  • 网站建设需要使用阿里云吗承包网站开发
  • Salesforce 知识点: Streaming API - 封装好的CometD
  • 【LangChain】P4 LangChain 多轮对话与上下文记忆深度解析
  • seo与网站建设的关联wordpress 留言插件
  • 订阅Apollo摄像头NPP颜色空间转换NVMPI硬编码输出RTSP服务
  • 营销网站设计公司有哪些网上购物都有哪些平台
  • 石家庄住房和城乡建设部网站互动营销平台
  • 站酷网怎么赚钱个人微信公众号
  • 什么网站可以自己做房子设计部署iis网站
  • 成都双语网站开发怎么找到当地的微信推广
  • 电子商务网站建设的方法与流程域名注册腾讯云
  • 腾讯网静态网站建设ppt网站超链接怎么做
  • 使用本地主机做网站富阳建设局网站
  • 基于秘密共享的门限签名
  • 专做宝宝的用品网站模板网站 建设教材
  • 如何建设一个专业的网站永久无限免费看的app
  • 房地产网站建设平台搜索关键词查询
  • 群晖做网站西安淘宝网站建设公司排名
  • 怎么查看网站外链效果网络营销sem