线程同步---信号量(无名)

作者:武汉味美食家餐饮管理有限公司 来源:www.cj17917.com 发布时间:2017-09-04 18:29:41
线程同步---信号量(无名)

1. 有名信号量&无名信号量

在POSIX标准中,信号量分两种,一种是无名信号量,一种是有名信号量。无名信号量只用于线程间的同步,有名信号量只用于进程间通信。信号量是属于POSIX:SEM的,不是属于POSIX:THR的,需要的文件头是。两者的共同点都是相当于计数器,用于限制多个进程对有限共享资源的访问

2. 相关函数

1)创建信号量

int sem_init (sem_t* sem, int pshared,unsigned int value);

sem - 信号量ID,输出。

pshared - 一般取0,表示调用进程的信号量。 非0表示该信号量可以共享内存的方式, 为多个进程所共享(Linux暂不支持)。

value - 信号量初值。

2)信号量操作函数

int sem_post (sem_t* sem);// 信号量加1 int sem_wait (sem_t* sem);//信号量减1,不够减即阻塞 int sem_trywait (sem_t* sem);// 信号量减1,不够减即返回-1,errno为EAGAIN int sem_timedwait (sem_t* sem, const struct timespec* abs_timeout);// 信号量减1,不够减即阻塞,直到abs_timeout超时返回-1,errno为ETIMEDOUT struct timespec { time_t tv_sec; // Seconds long tv_nsec; // Nanoseconds [0 - 999999999] }; int sem_getvalue(sem_t *sem, int *sval);//把 sem 指向的信号量当前值放置在 sval 指向的整数上

3) 销毁信号量

int sem_destroy (sem_t* sem);

3. 和互斥量的区别与联系:

互斥量任何时候都只允许一个线程访问共享资源, 而信号量则允许最多value个线程同时访问共享资源,当value为1时,与互斥量等价。

#include #include #include #include unsigned int g_cn = 0; sem_t g_sem; void* thread_proc (void* arg) { unsigned int i; for (i = 0; i < 100000; i++) { sem_wait (&g_sem); g_cn++; sem_post (&g_sem); } return NULL; } int main (void) { size_t i; pthread_t tids[2]; int error; sem_init (&g_sem, 0, 1); for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++) if ((error = pthread_create (&tids[i], NULL, thread_proc, NULL)) != 0) { fprintf (stderr, pthread_create: %s , strerror (error)); return -1; } for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++) if ((error = pthread_join (tids[i], NULL)) != 0) { fprintf (stderr, pthread_join: %s , strerror (error)); return -1; } sem_destroy (&g_sem); printf (g_cn = %u , g_cn); return 0; } 结果无论运行多少次,一直为20万

4. 模拟实习一个连接池问题,用来对有限资源的访问:

#include #include #include #include #include #define MAX_CONNS 5 // 最大连接数 #define MAX_USERS 50 // 最大用户数 sem_t g_sem; void* thread_user (void* arg) { pthread_t tid = pthread_self (); int sval; sem_getvalue (&g_sem, &sval); printf (%lu线程:等待数据库连接(还剩%d个空闲连接)... , tid, sval); sem_wait (&g_sem); sem_getvalue (&g_sem, &sval); printf (%lu线程:获得数据库连接(还剩%d个空闲连接)! , tid, sval); usleep (1000000); sem_post (&g_sem); sem_getvalue (&g_sem, &sval); printf (%lu线程:释放数据库连接(还剩%d个空闲连接)。 , tid, sval); return NULL; } int main (void) { size_t i; pthread_t tids[MAX_USERS]; int error; sem_init (&g_sem, 0, MAX_CONNS); //创建50个线程 for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++) if ((error = pthread_create (&tids[i], NULL, thread_user, NULL)) != 0) { fprintf (stderr, pthread_create: %s , strerror (error)); return -1; } //回收线程 for (i = 0; i < sizeof (tids) / sizeof (tids[0]); i++) if ((error = pthread_join (tids[i], NULL)) != 0) { fprintf (stderr, pthread_join: %s , strerror (error)); return -1; } //销毁信号量 sem_destroy (&g_sem); return 0; }

部分结果图:

\

企业建站2800元起,携手武汉肥猫科技,做一个有见地的颜值派!更多优惠请戳:武汉网站优化 http://www.feimao666.com

  • 上一篇:获取服务器上格式为JSON和XML两种格式的信息的小程序
  • 下一篇:最后一页
  • 
    COPYRIGHT © 2015 武汉味美食家餐饮管理有限公司 ALL RIGHTS RESERVED.
    本站所有原创信息,未经许可请勿任意转载或复制使用 网站地图 技术支持:肥猫科技
    精彩专题:网站建设
    购买本站友情链接、项目合作请联系客服QQ:2500-38-100