linux中pthread和shm的一些用法

来源:互联网 发布:常州网络电视台 编辑:程序博客网 时间:2024/05/24 04:07

使用fork或者pthread库来处理多线程问题。。。


1、共享内存使用方法
   1>定义一个共享内存的KEY: shm_key
   2>创建获取共享内存区域: key_t shmid = shmget(shm_key, 共享区域大小, IPC_CREAT | 0660)
   3>取得区享区域指针: char * addr = shmat(shmid, 0, 0);
   4>每个进程使用完毕后,需要关闭共享区域: shmdt(addr);
   5>主进程删除共享区域: shmctl(shmid, IPC_RMID, 0)


2、在使用共享内存的时候,需要注意数据的同步互斥,可使用pthread_mutex_t来处理互斥
   1>定义全局的互斥对象:pthread_mutex_t * g_mutex = NULL;
   2>初始化互斥对象:
         // 映射到进程共享
         g_mutex = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
         // 设置属性
         pthread_mutexattr_t attr;
         pthread_mutexattr_init(&attr);
         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
         pthread_mutex_init(g_mutex, &attr);
   3>互斥的使用:
         pthread_mutex_lock()
         pthread_mutex_unlock()
         将要保护的内容放置于两个中间,达到互斥访问的要求
   4>删除互斥对象
         pthread_mutex_destroy(g_mutex);
         munmap(g_mutex, sizeof(pthread_mutex_t));

// process_mutex.c

pthread_mutex_t * g_mutex = NULL;

struct shared_context
{
   int    ref_cnt;            // 计数器
   int    last_process;
};

#define key_shared_context 1234

int main(int argc, char * argv[])
{
   // 映射到进程共享
   g_mutex = mmap(NULL, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
   // 设置属性
   pthread_mutexattr_t attr;
   pthread_mutexattr_init(&attr);
   pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
   pthread_mutex_init(g_mutex, &attr);

    key_t shmid = shmget(key_shared_context, sizeof(struct shared_context), IPC_CREAT | 0660);
   struct shared_context * sctx = (struct shared_context*)shmat(shmid, 0, 0);

   if (fork() == 0)
   {
      // 子进程
      pthread_mutex_lock(g_mutex);

      struct shared_context * sctx = (struct shared_context*)shmat(shmid, 0, 0);
      sctx->ref_cnt++;
      sctx->process = getpid();
      shmdt((char*)sctx);
      pthread_mutex_unlock(g_mutex);
   }
   else
   {
      // 父进程
      pthread_mutex_lock(g_mutex);
      sctx->ref_cnt++;
      sctx->process = getpid();
      shmdt((char*)sctx);
      pthread_mutex_unlock(g_mutex);
   }
   shmctl(shmid, IPC_RMID);
   return 0;
}


使用pthread库来实现多线程

// thread.c

pthread_mutex_t g_mutex;

// 消耗过程
void * consume_proc(void * arg)
{
   printf("ready consume proc/n");
   pthread_mutex_lock(&mutex);
   printf("wait 5 sec for consume/n");
   sleep(5);
   printf("consume unlock/n");
   pthread_mutex_unlock(&mutex);
   printf("exit consume proc/n");
   return 0;
}

// 产生过程
void * build_proc(void * arg)
{
   printf("ready build proc/n");
   pthread_mutex_lock(&mutex);
   printf("wait 5 sec for build/n");
   sleep(5);
   printf("build unlock/n");
   pthread_mutex_unlock(&mutex);
   printf("exit build proc/n");
   return 0;
}


int main(int argc, char * argv[])
{
   // 使用线程时,处理互斥更为简单,不需要创建共享对象来供其他进程来使用
   pthread_mutex_init(&g_mutex);

   pthread_t thd_build, thd_consume;

   // 创建两个新线程
   pthread_create(&thread_build, NULL, &build_proc, NULL);
   pthread_create(&thread_consume, NULL, &consume_proc, NULL);

   // 等待线程的结束
   pthread_join(&thread_build);
   pthread_join(&thread_consume);

   pthread_mutex_destroy(&g_mutex);

   return 0;
}