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

网站页面创意产品推广策划书

网站页面创意,产品推广策划书,专做女鞋的网站代发广州,广告设计与制作专业就业工资文章目录 1、为什么要用互斥锁2、互斥锁怎么用3、为什么要用条件变量4、互斥锁和条件变量如何配合使用5、互斥锁和条件变量的常见用法 参考资料:https://blog.csdn.net/m0_53539646/article/details/115509348 1、为什么要用互斥锁 为了使各线程能够有序地访问公共…

文章目录

    • 1、为什么要用互斥锁
    • 2、互斥锁怎么用
    • 3、为什么要用条件变量
    • 4、互斥锁和条件变量如何配合使用
    • 5、互斥锁和条件变量的常见用法

参考资料:https://blog.csdn.net/m0_53539646/article/details/115509348

1、为什么要用互斥锁

为了使各线程能够有序地访问公共资源。例如:有一个全局变量g_count,有三个线程thread_fun_1、thread_fun_2、thread_fun_3,三个线程都要对g_count写操作。在不加锁的情况下,当thread_fun_1正在写数据时thread_fun_2和thread_fun_3也可能会进行写操作,这就会导致程序不符合我们的预期结果。而加锁的目的就是保证各线程能够按顺序访问公共资源,就好比我们排队WC一样,一个人解决完下个人才能解决。不多说,直接看下面的例子:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>static int g_count = 0; //共享数据static void *thread_fun_1(void *data)
{for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);
}static void *thread_fun_2(void *data)
{for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);
}static void *thread_fun_3(void *data)
{for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);
}int main(int argc, char const *argv[])
{pthread_t pid[3]; //创建3个线程pthread_create(&pid[0], NULL, thread_fun_1, NULL);pthread_create(&pid[1], NULL, thread_fun_2, NULL);pthread_create(&pid[2], NULL, thread_fun_3, NULL);//等待三个线程结束pthread_join(pid[0], NULL);pthread_join(pid[1], NULL);pthread_join(pid[2], NULL);return 0;
}

运行结果:

user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ gcc threadtest1.c -pthread 
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 10000
thread_fun_2 g_count: 20000
thread_fun_3 g_count: 30000
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 10000
thread_fun_2 g_count: 20437
thread_fun_3 g_count: 28812
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ 

例程解析:

上面的例程创建了3个线程,每个线程都对全局变量g_count加10000次,然后打印g_count的值。从运行结果很容易看出,同样的程序两次运行的结果不一致,这就是线程无序访问公共资源的原因。

2、互斥锁怎么用

说完为什么要用互斥锁,接下来就该说下怎么用了,步骤如下:

// 1、包含pthread.h头文件
#include <pthread.h>// 2、互斥锁的声明
static pthread_mutex_t g_mutex_lock//3、互斥锁的初始化
pthread_mutex_init(&g_mutex_lock, NULL);// 4、锁定互斥锁
pthread_mutex_lock(&g_mutex_lock);// 5、执行对共享资源的操作// 6、解锁互斥锁
pthread_mutex_unlock(&g_mutex_lock);// 7、销毁互斥锁
pthread_mutex_destroy(&g_mutex_lock);

接着上面的例子,写一个带互斥锁的程序:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>static int g_count = 0; //共享数据
static pthread_mutex_t g_mutex_lock;static void *thread_fun_1(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁
}static void *thread_fun_2(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁
}static void *thread_fun_3(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁for(int i=0; i<10000; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁
}int main(int argc, char const *argv[])
{int ret;pthread_t pid[3];ret = pthread_mutex_init(&g_mutex_lock, NULL);if (ret != 0) {printf("mutex init failed\n");return -1;}pthread_create(&pid[0], NULL, thread_fun_1, NULL);pthread_create(&pid[1], NULL, thread_fun_2, NULL);pthread_create(&pid[2], NULL, thread_fun_3, NULL);pthread_join(pid[0], NULL);pthread_join(pid[1], NULL);pthread_join(pid[2], NULL);pthread_mutex_destroy(&g_mutex_lock);
}

运行结果:

user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ gcc threadtest2.c -pthread 
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 10000
thread_fun_2 g_count: 20000
thread_fun_3 g_count: 30000
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 10000
thread_fun_2 g_count: 20000
thread_fun_3 g_count: 30000
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 10000
thread_fun_2 g_count: 20000
thread_fun_3 g_count: 30000
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ 

从上面的结果可以看到,程序多次运行,执行结果都是一样的

3、为什么要用条件变量

相信大家到这里会有一个疑问,既然互斥锁都能保证程序有序访问了,为什么还要使用条件变量呢?我们看下面的例子:下面代码创建了thread_fun_1和thread_fun_2两个线程,thread_fun_2中对g_count全局变量加100次,thread_fun_1中判断全局变量的值大于0才执行。按照我们的理解,两个线程都能正常运行退出才对,但实际运行结果并不是这样。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>static int g_count = 0; //共享数据
static pthread_mutex_t g_mutex_lock;static void *thread_fun_1(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁printf("%s g_count: %d\n", __func__, g_count);while(0 < g_count){//do somethingprintf("%s run ok,g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁break;}
}static void *thread_fun_2(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁for(int i=0; i<100; i++){g_count++;}printf("%s g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁}int main(int argc, char const *argv[])
{int ret;pthread_t pid[3];ret = pthread_mutex_init(&g_mutex_lock, NULL);if (ret != 0) {printf("mutex init failed\n");return -1;}pthread_create(&pid[0], NULL, thread_fun_1, NULL);pthread_create(&pid[1], NULL, thread_fun_2, NULL);pthread_join(pid[0], NULL);pthread_join(pid[1], NULL);pthread_mutex_destroy(&g_mutex_lock);
}

运行结果:可以看到线程thread_fun_1打印了一串日之后就没有其他打印了,程序像是阻塞了一样。其实这里是进入了死锁,g_count一开始初始化为0:当 thread_fun_1进入临界区时,其他线程不能进入临界区,意味着 Bthread_fun_2没有机会去修改 g_count, g_count的值一直为 0,不满足Athread_fun_1继续执行的条件(g_count> 0),Athread_fun_1只能一直等待。 又因为使用了互斥锁:当 thread_fun_1进入临界区时,其他线程不能进入临界区,意味着 thread_fun_2没有机会去修改 g_count, g_count 的值一直为 0,不满足thread_fun_1继续执行的条件(g_count > 0)。最终结果:thread_fun_1只能一直等待,thread_fun_2不能执行,导致整个程序不能正常运行。这时候就需要使用条件变量了。

user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ gcc threadtest3.c -pthread 
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 0

4、互斥锁和条件变量如何配合使用

使用步骤:

// 1、包含pthread.h头文件
#include <pthread.h>// 2、条件变量声明
pthread_cond_t g_cond ; //3、条件初始化
pthread_cond_init(&g_cond, NULL) ;// 4、/* 令一个线程A等待在条件变量上 */
pthread_cond_wait(&g_cond, &g_mutex_lock) ;// 5、线程B执行对共享资源的操作// 6、线程B通知等待在条件变量上的线程A,线程通知函数有2个,pthread_cond_broadcast是通知所有线程
//    pthread_cond_signal是至少通知一个线程,一般使用pthread_cond_broadcast函数
pthread_cond_broadcast(&g_cond) ;
pthread_cond_signal(&g_cond);// 7、销毁条件变量
pthread_cond_destroy( &g_cond ) ;

我们通过条件变量解决上面的问题:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>static int g_count = 0; //共享数据
static pthread_mutex_t g_mutex_lock;//互斥锁
pthread_cond_t g_cond ; //条件变量static void *thread_fun_1(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁printf("%s g_count: %d\n", __func__, g_count);pthread_cond_wait(&g_cond, &g_mutex_lock) ;while(0 < g_count){//do somethingprintf("%s run ok,g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁break;}
}static void *thread_fun_2(void *data)
{pthread_mutex_lock(&g_mutex_lock); //上锁for(int i=0; i<100; i++){g_count++;pthread_cond_broadcast(&g_cond) ;}printf("%s g_count: %d\n", __func__, g_count);pthread_mutex_unlock(&g_mutex_lock); //解锁}int main(int argc, char const *argv[])
{int ret;pthread_t pid[3];pthread_cond_init(&g_cond, NULL) ;ret = pthread_mutex_init(&g_mutex_lock, NULL);if (ret != 0) {printf("mutex init failed\n");return -1;}pthread_create(&pid[0], NULL, thread_fun_1, NULL);pthread_create(&pid[1], NULL, thread_fun_2, NULL);pthread_join(pid[0], NULL);pthread_join(pid[1], NULL);pthread_cond_destroy( &g_cond ) ;pthread_mutex_destroy(&g_mutex_lock);
}

运行结果:

user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ gcc threadtest4.c -pthread 
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ ./a.out 
thread_fun_1 g_count: 0
thread_fun_2 g_count: 100
thread_fun_1 run ok,g_count: 100
user@root:/mnt/hgfs/UbuntuRK3568/04_ThreadLockTest$ 

5、互斥锁和条件变量的常见用法

一般做项目的时候如果我们希望多个线程使用同一资源,我们一般会将这部分资源打包成一个结构体,通过结构体定义一个全局变量供各线程使用。所以,互斥锁和条件变量一般也是和结构体一起用的,如下面的例子,加锁、解锁还有初始化跟上面的举的例子一样,放在结构体表示对该结构体的数据进行加锁。

typedef struct 
{int a;char buf[32];/* ... */pthread_mutex_t mutex_test;pthread_cond_t cond_test;
} test;

就写这么多吧,如果哪里有问题欢迎大家指正。


文章转载自:
http://dinncoconverge.stkw.cn
http://dinncosoupcon.stkw.cn
http://dinncoshowman.stkw.cn
http://dinncofantasize.stkw.cn
http://dinncopavilion.stkw.cn
http://dinncodiscontinue.stkw.cn
http://dinncoimpression.stkw.cn
http://dinncoregna.stkw.cn
http://dinncooverspray.stkw.cn
http://dinnconaif.stkw.cn
http://dinncowigwam.stkw.cn
http://dinncoreconvert.stkw.cn
http://dinncokhansu.stkw.cn
http://dinncosaturable.stkw.cn
http://dinncoforensic.stkw.cn
http://dinncorighteous.stkw.cn
http://dinncosuperego.stkw.cn
http://dinncopunctate.stkw.cn
http://dinncoenthymeme.stkw.cn
http://dinncoperforce.stkw.cn
http://dinncoaproposity.stkw.cn
http://dinncobepaint.stkw.cn
http://dinncoroadside.stkw.cn
http://dinncopostnuptial.stkw.cn
http://dinncogetable.stkw.cn
http://dinncoantilepton.stkw.cn
http://dinncodemagogue.stkw.cn
http://dinncosarcophagi.stkw.cn
http://dinncohornpout.stkw.cn
http://dinncocuddly.stkw.cn
http://dinncosplenalgia.stkw.cn
http://dinncodumdum.stkw.cn
http://dinncoexaggerative.stkw.cn
http://dinncocraziness.stkw.cn
http://dinncokantism.stkw.cn
http://dinncoliving.stkw.cn
http://dinncounicolour.stkw.cn
http://dinncophallic.stkw.cn
http://dinncotome.stkw.cn
http://dinncoskolly.stkw.cn
http://dinncosplad.stkw.cn
http://dinncooracle.stkw.cn
http://dinncoexplant.stkw.cn
http://dinncosister.stkw.cn
http://dinncononrefundable.stkw.cn
http://dinncorheinland.stkw.cn
http://dinncopeyotl.stkw.cn
http://dinncocalendarian.stkw.cn
http://dinncogrowing.stkw.cn
http://dinncojangler.stkw.cn
http://dinncoila.stkw.cn
http://dinncoramark.stkw.cn
http://dinncolunitidal.stkw.cn
http://dinncoanuric.stkw.cn
http://dinncomorty.stkw.cn
http://dinncoeugenic.stkw.cn
http://dinncoinconscient.stkw.cn
http://dinncoinferoanterior.stkw.cn
http://dinncopuseyite.stkw.cn
http://dinncowirk.stkw.cn
http://dinncohectic.stkw.cn
http://dinncointerleaved.stkw.cn
http://dinncosmallholding.stkw.cn
http://dinncobon.stkw.cn
http://dinncolapidicolous.stkw.cn
http://dinncouso.stkw.cn
http://dinncokidney.stkw.cn
http://dinncohouse.stkw.cn
http://dinncostripline.stkw.cn
http://dinncosalutiferous.stkw.cn
http://dinncorattly.stkw.cn
http://dinncoareographer.stkw.cn
http://dinncocruor.stkw.cn
http://dinnconescience.stkw.cn
http://dinncoucayali.stkw.cn
http://dinncoacerbating.stkw.cn
http://dinncosjd.stkw.cn
http://dinncochez.stkw.cn
http://dinncococcidiosis.stkw.cn
http://dinncowhaleback.stkw.cn
http://dinncocolumbic.stkw.cn
http://dinncobookend.stkw.cn
http://dinncokrans.stkw.cn
http://dinncowaveshape.stkw.cn
http://dinncounprophetic.stkw.cn
http://dinncohooknose.stkw.cn
http://dinncocounterdraw.stkw.cn
http://dinncoshrug.stkw.cn
http://dinncolowball.stkw.cn
http://dinncortol.stkw.cn
http://dinncothingumajig.stkw.cn
http://dinncoparking.stkw.cn
http://dinncounexpressive.stkw.cn
http://dinncoenunciability.stkw.cn
http://dinncobricoleur.stkw.cn
http://dinncoangleworm.stkw.cn
http://dinncostride.stkw.cn
http://dinncosuburbanise.stkw.cn
http://dinncobloodthirsty.stkw.cn
http://dinncopiliated.stkw.cn
http://www.dinnco.com/news/155421.html

相关文章:

  • wordpress 制作优化大师官方网站
  • 陕西西安网站建设公司数据分析系统
  • aspnet动态网站开发期末考试上海专业做网站
  • 移动端网页百度seo培训课程
  • 免费空间 网站搜索引擎提交入口大全
  • 网站怎么做淘宝客百度的营销推广模式
  • 宁夏网站建设多少钱中国域名注册局官网
  • 淘宝的网站开发历史及难度百度运营公司
  • 重庆龙头寺找做墩子师傅网站线上营销方案
  • 杭州网站推广公司企业seo推广外包
  • 网站制作的流程包括哪些百度知道官网首页登录入口
  • 考互联网营销师证书要多少钱重庆百度seo代理
  • 浏览器网站建设的步骤过程微信软文是什么意思
  • 国外电子商务网站微信公众平台开发
  • 关键词 网站网销怎么做
  • 网站建设公司做销售前景好不好深圳网络广告推广公司
  • 中国icp备案的有多少企业网站优化技术基础
  • 做网站参考文献卡一卡二卡三入口2021
  • 网络科技公司经营范围参考东莞网站优化关键词排名
  • iis网站301重定向站长统计app软件下载官网
  • 手机做炫光头像图的网站seo入门视频
  • 长春网站制作费用浙江专业网站seo
  • 房屋 哪个网站做的最好seo排名快速优化
  • wordpress安装在哪关键词在线优化
  • wordpress怎么改标题哈尔滨网络优化公司有哪些
  • 赤峰网站建设抖音视频排名优化
  • 企业网站需要多少钱线上推广是什么意思
  • 网站怎么换域名百度快照投诉中心人工电话
  • 男人互做网站百度seo排名优化价格
  • 高端网站设计公司名单中国宣布疫情结束日期