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

网站底部固定代码免费做店招的网站

网站底部固定代码,免费做店招的网站,开发一个非常简单的聊天软件,云空间网站怎么做线程间的通信即多个线程间传递信息。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/505856.html

相关文章:

  • 响应式网站建设服务广告公司名字大全简单
  • 找哪里做网站基本网站怎么做
  • python网站开发学习网站seo设置是什么
  • 怎样建设网站教程上海设计公司电话
  • 网站开发需要什么基础只是做石膏选图形的网站
  • 深圳罗湖住房和建设局网站wordpress时钟插件
  • 西安做网站哪家便宜建设西安网站
  • 手机参数查询网站手机网页版微信登录入口
  • 温州网站专业制作wordpress炫酷模板下载
  • 网站 数据库 sql 导入数据库文件有没有帮人做简历的网站
  • 服装网站建设规划建站之星 网站排名
  • 上海建筑网站设计网站建设与推广的策划方案
  • 做个网站多少钱如何搭建微信公众号平台
  • 网站建设公司做前端餐饮公司企业网站源码
  • 做网站所用的工具襄阳市做网站 优帮云
  • iapp网站做软件教程临沂seo网站管理
  • 网站推广软件信息百度快照推广效果怎样
  • 网页设计欣赏网站网站后期推广方案
  • 网站开发有哪些工作岗位招聘平台
  • 网站百度收录怎么做广州创建网站
  • 主要的网站开发技术网站负责人照片
  • 百度建立企业网站建设的目的企业为什么要建立自己的网站
  • 网站建设行业标准备案添加网站
  • 搜索敏感词后很多网站打不开了二维码网页制作免费网站制作
  • ip网站查询服务器企业建站 wordpress
  • 网站的运营模式女同性做的视频网站
  • 什么软件可以做动漫视频网站模板网字库
  • 黄骅做网站的电话免费网站推广网站在线
  • 购物网站模板站深圳网页制作与网站建设地址
  • 多个域名 一个网站电脑ps软件哪个好