关闭

Linux 多线程编程( POSIX )( 三 )------->代码区 ( 信号灯实例 )

标签: 多线程linux编程null测试join
1237人阅读 评论(0) 收藏 举报
分类:
1.sem_open与sem_close与sem_unlink与sem_getvalue

#include <stdio.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main( int argc, char ** argv )
{
sem_t * sem;
int val;

if( argc != 2 )
{
printf("请输入文件名!\n");
exit( EXIT_FAILURE );
}

//!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//!> 创建信号灯

if( ( sem = sem_open( argv[1], O_CREAT, 0644, 1 ) ) == SEM_FAILED )
{ //!> if 失败,报错... ...
printf("创建信号灯失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("创建信号灯OK ...\n");
}

//!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//!> 获取指定信号灯的当前值

if( sem_getvalue( sem, &val ) != 0 )
{
printf("获取值失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("获取值为VAL == %d\n", val);
}

//!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//!> 关闭信号灯

if( sem_close( sem ) != 0 )
{
printf("Close 信号灯失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("Close 信号灯OK....\n");
}

//!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//!> 删除信号灯

if( sem_unlink( argv[1] ) != 0 )
{
printf("删除信号灯失败....\n");
exit( EXIT_FAILURE );
}
else
{
printf("删除信号灯成功...\n");
}

return 0;
}
结果:
创建信号灯OK ...
获取值为VAL == 1
Close 信号灯OK....
删除信号灯成功...

2.测试sem_close与sem_unlink不一样

//!> 测试sem_close与sem_unlink不一样
//!> 也就证明close后,再次重启一个进程还
//!> 可以访问没有删除的信号灯
//!> 创建一个名称为“shanshan”的信号灯

//!> CODE 1

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>

int main( int argc, char ** argv )
{
sem_t * sem;

if( argc != 2 )
{
printf("请输入文件名....\n");
exit( EXIT_FAILURE );
}

if( ( sem = sem_open( argv[1], O_CREAT, 0644, 1 ) ) == SEM_FAILED ) //!> Create
{
printf("创建信号灯失败....\n");
exit( EXIT_FAILURE );
}
else
{
printf( "创建信号灯OK...\n" );
}

sem_close( sem ); //!> Close

return 0;
}

终端Copy:
pt@ubuntu:~/桌面/net programming/5_线程通信_POSIX_5/3_信号灯_3/CODE/测试关闭 != 删除$ ./t1 shanshan
创建信号灯OK...

//!> 测试sem_close与sem_unlink不一样
//!> 也就证明close后,再次重启一个进程还
//!> 可以访问没有删除的信号灯
//!> 创建一个名称为“shanshan”的信号灯

//!> CODE 2

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>

int main( int argc, char ** argv )
{
sem_t * sem = NULL;

sem = sem_open( argv[1], 0 ); //!> 打开已经创建的信号灯
//!> 没有创建哦~
if( sem && sem != SEM_FAILED ) //!> Success
{
printf("打开已经创建的信号灯OK ...\n");
}
else
{
printf("打开已经创建的信号灯失败...\n");
exit( EXIT_FAILURE );
}

sem_close( sem ); //!> 关闭
sem_unlink( argv[1] ); //!> 删除

return 0;
}
终端Copy:
pt@ubuntu:~/桌面/net programming/5_线程通信_POSIX_5/3_信号灯_3/CODE/测试关闭 != 删除$ ./t2 shanshan
打开已经创建的信号灯OK ...

//!> 注意:终端输入的参数与CODE 1应该是一样的!!!


3.sem_wait测试

//!> 创建多线程并使用sem_wait互斥
//!> 做1+2+...+10

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>

int g_i = 0; //!> 全局增量(共享变量)
int g_sum = 0; //!> 结果保存(共享变量)
sem_t * sem; //!> 创建一个信号量

//!> 创建信号灯
void create_sem( char name[] )
{
if( ( sem = sem_open( name, O_CREAT, 0644, 1 ) ) == SEM_FAILED )
{
printf("创建信号灯失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("创建信号灯OK....\n");
}
}

//!> 线程1入口
void * entrance_1( void * arg )
{
for( g_i = 0; g_i < 11; g_i++ )
{
sem_wait( sem ); //!> 加锁

printf( "线程1在执行....\n" );
g_sum += g_i;

sem_post( sem ); //!> 解锁
sleep( 2 );
}
}

//!> 线程2入口
void * entrance_2( void * arg )
{
for( g_i = 0; g_i < 11; g_i++ )
{
sem_wait( sem ); //!> 加锁

printf( "线程2在执行....\n" );
g_sum += g_i;

sem_post( sem ); //!> 解锁
sleep( 3 );
}
}

//!> 创建两个线程
void create_threads( pthread_t * ptid1, pthread_t * ptid2 )
{
if( pthread_create( ptid1, NULL, entrance_1, NULL ) != 0 )
{
printf("创建线程1失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("创建线程1OK ....\n");
}

if( pthread_create( ptid2, NULL, entrance_2, NULL ) != 0 )
{
printf("创建线程2失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("创建线程2OK ....\n");
}
}

//!> do and wait
void do_and_wait( pthread_t tid1, pthread_t tid2 )
{
if( tid1 != -1 )
{
pthread_join( tid1, NULL );
}
else
{
printf("线程1错误...\n");
exit( EXIT_FAILURE );
}

if( tid2 != -1 )
{
pthread_join( tid2, NULL );
}
else
{
printf("线程2错误...\n");
exit( EXIT_FAILURE );
}
}

//!> 关闭and删除信号灯
void close_and_del_sem( char * name )
{
if( sem_close( sem ) != 0 )
{
printf("关闭信号灯失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("关闭信号灯OK ...\n");
}

if( sem_unlink( name ) != 0 )
{
printf("删除信号灯失败...\n");
exit( EXIT_FAILURE );
}
else
{
printf("删除信号灯OK....\n");
}

}

int main( int argc, char ** argv )
{
pthread_t tid1 = -1;
pthread_t tid2 = -1; //!> 创建两个线程

if( argc != 2 )
{
printf("请输入文件名!\n");
exit( EXIT_FAILURE );
}

create_sem( argv[1] ); //!> 创建信号灯
create_threads( &tid1, &tid2 ); //!> 创建线程
do_and_wait( tid1, tid2 ); //!> 子线程处理+等待子线程
close_and_del_sem( argv[1] ); //!> 关闭和删除信号灯

printf("子线程运行结束!\n");
printf("结果g_sum == %d\n", g_sum);
printf("我是主线程,我的 ID == %d\n", (unsigned)pthread_self());

return 0;
}
./c shanshan
结果:
创建信号灯OK....
创建线程1OK ....
创建线程2OK ....
线程1在执行....
线程2在执行....
线程1在执行....
线程2在执行....
线程1在执行....
线程2在执行....
线程1在执行....
线程1在执行....
线程2在执行....
线程1在执行....
线程2在执行....
线程1在执行....
关闭信号灯OK ...
删除信号灯OK....
子线程运行结束!
结果g_sum == 55
我是主线程,我的 ID == 927221504

4.应用Posix有名信号灯。限制访问共享代码的进程数目

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>

sem_t * sem; //!> 信号灯
int val; //!> 信号灯当前值


void print_info( pid_t pid )
{
printf("我的ID == %d\n", (int)pid);
sem_getvalue( sem, &val );
printf("当前信号灯值 == %d\n", val);
}

int main( int argc, char ** argv )
{
int i = 0;

if( argc != 2 )
{
printf("请输入文件名!\n");
exit( EXIT_FAILURE );
}

if( sem_open( argv[1], O_CREAT, 0644, 2 ) == SEM_FAILED ) //!> 初始化有两个可用src
{
printf("创建信号灯失败...\n");
exit( EXIT_FAILURE );
}

while( i++ < 5 )
{
if( fork() 0= 0 ) //!> 创建进程
{
sem_wait( sem ); //!> P 操作
print_info( getpid() );
sleep(1);
sem_post( sem ); //!> V 操作
printf("我的ID == %d, 运行结束....\n", (int)getpid());
return 0;
}
}

wait();
sem_close( sem ); //!> 关闭
sem_unlink( argv[1] ); //!> 删除
return 0;
}


5.应用posix基于内存的信号灯实现一个进程的各个线程间的互斥

#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <pthread.h>

sem_t sem; //!> 信号灯
int value; //!> 信号量


void * entrance( void * arg )
{
sem_wait( &sem ); //!> 计数信号灯
print_info();
sleep( 2 );
sem_post( &sem ); //!> V 操作

printf("我的ID == %d, 运行结束....\n", (unsigned)pthread_self());
pthread_exit( arg );

}

void print_info()
{
printf("输出线程ID == %d\n", (unsigned)pthread_self());
sem_getvalue( &sem, &value );
printf( "信号灯当前数量: %d\n", value );
}

int main( )
{
int n = 0;
pthread_t tid;

if( sem_init( &sem, 0, 2 ) != 0 ) //!> 线程共享,量==2
{
printf("sem_init 失败...\n");
exit( EXIT_FAILURE );
}

while( n++ < 5 ) //!> 创建5个线程
{
if( pthread_create( &tid, NULL, entrance, NULL ) != 0 )
{
printf("创建线程 %d 失败....\n", n);
exit( EXIT_FAILURE );
}
}

pthread_join( tid, NULL );

return 0;
}


2
0
查看评论

Posix多线程编程学习笔记(一)

Posix多线程编程学习笔记(一)—线程基础(1) 一.什么是线程        在一个程序里的多个执行路线就叫做线程。更准确的定义是:线程是“一个进程内部的一个控制序列”。    &#...
  • liuhongxiangm
  • liuhongxiangm
  • 2012-12-17 18:09
  • 3999

linux--posix多线程编程----第一篇

一   线程创建 1.1 线程与进程 相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。在串行程序基础上引入线程和进程是为了提高程序的并发度,从而提高程序运行效率和响应时间。 线程...
  • u010358881
  • u010358881
  • 2015-09-25 14:14
  • 588

Linux 多线程编程( POSIX )( 三 )------->代码区

转自:http://blog.sina.com.cn/s/blog_6dc9e4cf0100xdfc.html 1.sem_open与sem_close与sem_unlink与sem_getvalue #include #include #include #inclu...
  • sweet_life
  • sweet_life
  • 2013-05-20 14:14
  • 574

Linux 多线程编程( POSIX )( 三 )------->信号灯

Attention:代码区链接 一.       POSIX有名信号灯     所谓有名就是给一个类似句柄的key。      ...
  • shanshanpt
  • shanshanpt
  • 2012-03-21 06:41
  • 1367

Linux 多线程编程( POSIX )( 四 )------>代码区 ( 互斥量实例 )

加锁与不加锁的对比: //!>不加锁测试 //!>简单的售票小测试程序 #include #include #include #include #include int        ...
  • shanshanpt
  • shanshanpt
  • 2012-03-21 06:42
  • 1178

Linux 多线程编程( POSIX )( 六 )----->代码区 ( 共享内存实例 )

注意:以下编译加上  -lrt 例如:gcc  -o server  server.c  -lrt 1.创建一个共享内存区的例子 #include #include #include #include int mai...
  • shanshanpt
  • shanshanpt
  • 2012-03-21 06:48
  • 1099

Linux 多线程编程( POSIX )( 五 )----->代码区 ( 条件变量实例 )

1.条件变量的基本作用 //!> 条件变量的基本作用 #include #include #include //!> 注意此处为了方便就使用静态变量吧 pthread_mutex_t      ...
  • shanshanpt
  • shanshanpt
  • 2012-03-21 06:45
  • 1172

Linux 多线程编程( POSIX )( 二 )----->代码区

转自:http://blog.sina.com.cn/s/blog_6dc9e4cf0100xcvk.html 1.detach实例: //!> detach #include #include #include void * entrance( void *...
  • sweet_life
  • sweet_life
  • 2013-05-20 14:13
  • 553

Linux 多线程编程( POSIX )( 一 ) ----> 代码区

1.基础线程创建: #include #include #include void * print_id( void * arg)       //!>这是线程的入口函数   &#...
  • shanshanpt
  • shanshanpt
  • 2012-03-20 12:09
  • 1062

C++之多线程(POSIX多线程实例)

转载自:http://blog.csdn.net/hitwengqi/article/details/8015646 1.进程同时创建5个线程,各自调用同一个函数 #include #include //多线程相关操作头文件,可移植众多平台 using namespace std; #defi...
  • liuweiyuxiang
  • liuweiyuxiang
  • 2016-06-14 15:39
  • 847
    个人资料
    • 访问:632527次
    • 积分:7099
    • 等级:
    • 排名:第3818名
    • 原创:182篇
    • 转载:36篇
    • 译文:0篇
    • 评论:84条
    博客专栏