进程间通信

来源:互联网 发布:瓦尔特刀具软件 编辑:程序博客网 时间:2024/05/29 16:50

原创: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_createerror");
 }
 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_createerror");
 }
 
 while(1)
 {
  sleep(5);
  break;
 }
 printf("main exit\n");
}

五、线程间的同步
  用信号量:
  int sem_init(sem_t *sem,int pshared,unsignedvalue);
  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_produceover");
}

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

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_createerror...\n");
 }
 //生产
 rlt =pthread_create(&threadProId, NULL, pthread_produce,NULL);
 
 if( rlt !=0 )
 {
  ERR_EXIT("pthread_createerror...\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_twork_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_twork_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);
}

 

 

 

 

原创粉丝点击