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

来源:互联网 发布:123网络测速 编辑:程序博客网 时间:2024/05/22 02:30

转自:http://blog.sina.com.cn/s/blog_6dc9e4cf0100xdfc.html


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");
    }

    return0;
}
       结果:
       创建信号灯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

    return0;
}

终端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] );         //!> 删除
   
    return0;
}
终端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());
   
    return0;
}
    ./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());
          return0;
       }
    }

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


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_ttid;

    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 );
   
    return0;
}

原创粉丝点击