进程间通信

原创:http://blog.sina.com.cn/u/2312748742

 

linux 线程
一、线程的创建:
  1) int pthread_create(pthread_t *thread,pthread_attr_t *attr,
                      void*(*start_routine)(void*),void *arg)
  2)thread:新线程创建成功后,保存新线程的标识符。
  3)attr:设置线程的属性,可用NULL.
  4)start_routine:函数的地址。回调函数。
  5)arg:传给线程启动参数的参数。
二、结束回调函数:
  1)void pthread_exit(void *retbal);
   返回一个指向某个对象的指针。不能返回一个指向局部变量的指针
三、线程结束后归并到一起。
  1)int pthread_join(pthread_t th,void **thread_return);
  2)th 指定将要等待的线程标识符。
  3)thread_return:指向另一个指针。后者指向线程返回值。
  4)pthread_join相当于进程用来等待子进程的wait函数。
 
四、编译时用g++ -o pthread pthread.cpp -lpthread  (-lpthread为链接到动态库中)
 
例子:非绑定,要手动清除
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>


#define ERR_EXIT(m) do \
{ \
 perror(m); \
 exit(EXIT_FAILURE); \
} while(0)

void* pthread_start(void*)
{
 printf("hello world\n");
 sleep(1);
 pthread_exit((void *)"pthread over\n");
 
}


int main()
{
 pthread_t threadId=0;
 //pthread_attr_t attr;
  //pthread_attr_init(&attr); //初始化属性
 //pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);//绑定
 //pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//分离
 int rlt= pthread_create(&threadId,NULL,pthread_start,NULL);
 if(rlt!=0)
 {
  ERR_EXIT("pthread_create error");
 }
 void *thread_return;
 rlt=pthread_join(threadId, &thread_return); //回调函数的返回值
 printf("%s",thread_return);
}


绑定,设置自动分离
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>


#define ERR_EXIT(m) do \
{ \
 perror(m); \
 exit(EXIT_FAILURE); \
} while(0)

void* pthread_start(void*)
{
 printf("hello world\n");
 sleep(1);
 pthread_exit((void *)"pthread over\n");
 
}


int main()
{
 pthread_t threadId=0;
 pthread_attr_t attr;
  pthread_attr_init(&attr); //初始化属性
 pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);//绑定
 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//分离
 int rlt= pthread_create(&threadId,NULL,pthread_start,NULL);
 if(rlt!=0)
 {
  ERR_EXIT("pthread_create error");
 }
 
 while(1)
 {
  sleep(5);
  break;
 }
 printf("main exit\n");
}

五、线程间的同步
  用信号量:
  int sem_init(sem_t *sem,int pshared,unsigned value);
  1)sem  要进行初始化的信号量对象。
  2)pshared 控制着信号量的类型 0:线程间。非0:进程间
  3)value 赋给信号量对象的一个整数类型的初始值。
  4)调用成功返回0
六、p操作,减1操作
  int sem_wait(sem_t *sem);
七、V操作,加1操作
  int sem_post(sem_t *sem);
八、用完信号量后,要对信号量进行清理
  int sem_destroy(sem_t *sem);
例子:
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>


#define ERR_EXIT(m) do \
{ \
 perror(m); \
 exit(EXIT_FAILURE); \
} while(0)


int glb_Max = 10;    //要设为全局变量
//同步信号量  生产数量
sem_t semPruc;
//同步信号量  可消费数量
sem_t semConsum;


void* pthread_produce(void*)
{
 int max = 10;
 while(true)
 {
  //还可以生产几个
  sem_wait(&semPruc);  //生产信号量-1
  printf("pthread_produce: produce one..\n");
  //writeLog()
  sleep(1);
  sem_post(&semConsum); //消费信号量+1
  max--;
  if(max <=0)
  {
   break;
  }
 
 pthread_exit((void *)"pthread_produce over");
}

void* pthread_consume(void*)
{
 int max = 10;
 while(true)
 {
 //还可以生产几个
  sem_wait(&semConsum); //消费信号量-1
  
  printf("pthread_consume: consume one..\n");
  sleep(3);
  sem_post(&semPruc); //生产信号量+1
  max--;
  if(max <=0)
  {
   break;
  }
 }
 pthread_exit((void *)"pthread_consume over");
}

void writeLog(char *info)
{
 //互斥锁
 
 //
}

int main()
{
 pthread_t threadConId = 0;
 pthread_t threadProId = 0;
 
 //信号量初始化
 int rlt = sem_init(&semPruc,0,6);//最多允许生产6个 6个资源数
 rlt = sem_init(&semConsum, 0, 0);
 
 //消费
 rlt = pthread_create(&threadConId, NULL, pthread_consume, NULL);
 if( rlt !=0 )
 {
  ERR_EXIT("pthread_create error...\n");
 }
 //生产
 rlt = pthread_create(&threadProId, NULL, pthread_produce, NULL);
 
 if( rlt !=0 )
 {
  ERR_EXIT("pthread_create error...\n");
 }
 
 sem_destroy(&semConsum); //销毁信号量
 sem_destroy(&semPruc); 
 pthread_join(threadConId, NULL); //等待信号量没有这个的话就会强制结束线程
 pthread_join(threadProId, NULL);
}

--------------------------------------------------------------------------

互斥锁机制,保护关键代码段:

例子:

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

void * thread_func(void *arg);

pthread_mutex_t work_mutex;//=PTHREAD_MUTEX_INITIALIZER;//初始化
int g_num = 0;

int main() {
 int res;
 pthread_t a_thread;
 void *thread_result;
 res = pthread_mutex_init(&work_mutex,NULL);
 res = pthread_create(&a_thread,NULL,thread_func,NULL);
 sleep(2);
 
 pthread_mutex_lock(&work_mutex);
 g_num ++;
 printf("Waiting for thread to joined \n");
 pthread_mutex_unlock(&work_mutex);
 
 res = pthread_join(a_thread,&thread_result);
 printf("thread joined\n");
 exit(0);
}

void* thread_func(void *arg)
{
 printf("Sub Thread running now.\n");
 pthread_mutex_lock(&work_mutex);
 sleep(4);
 printf("g_num in subThread is %d\n",g_num);
 pthread_mutex_unlock(&work_mutex);
 pthread_exit(0);
}

执行后显示:

Sub Thread running now

g_num in subThread is 0

Waiting for thread to joined

thread joined

---------------------------------------------------------

防止死锁方法:

1)设置超时线程,定期检查

2)pthread_cleanup_push();和pthread_cleanup_pop()//可以看成是{ } 当跳出时就会unlock
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>

void * thread_func(void *arg);

pthread_mutex_t work_mutex;//=PTHREAD_MUTEX_INITIALIZER;//初始化
int g_num = 0;

int main() {
 int res;
 pthread_t a_thread;
 void *thread_result;
 res = pthread_mutex_init(&work_mutex,NULL);
 res = pthread_create(&a_thread,NULL,thread_func,NULL);
 sleep(2);
 
 pthread_mutex_lock(&work_mutex);
 g_num ++;
 printf("Waiting for thread to joined \n");
 pthread_mutex_unlock(&work_mutex);
 
 res = pthread_join(a_thread,&thread_result);
 printf("thread joined\n");
 exit(0);
}

void* thread_func(void *arg)
{
 printf("Sub Thread running now.\n");
  pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, &work_mutex); //{
 pthread_mutex_lock(&work_mutex);
 sleep(4);
 printf("g_num in subThread is %d\n",g_num);
 pthread_exit(0);
 pthread_mutex_unlock(&work_mutex);
pthread_cleanup_pop(0);//}  //只要跳出花括号就会进行解锁 如果有两个就在写一遍,变成2 { {} }
 
 pthread_exit(0);
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值