一、线程的创建与应用
1、线程函数
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
功能: 创建一个线程
参数1:thread----------
带回线程号
参数2:attr ------- 创建线程的属性
NULL
参数3:是函数指针,有void*
参数, 返回
void*
参数4:arg---------- 就是上边的函数指针指向的函数的参数
返回值:
成功, 返回0
失败, 返回-1
int pthread_join(pthread_t thread, void **retval);
功能: 回收线程
参数1: thread ---
要回收的线程号
参数2:retval ------ 二级指针,带回线程的返回值
返回值:
成功, 返回0
失败, 返回-1
void pthread_exit(void *retval);
功能: 结束线程,线程返回
retval
int pthread_cancel(pthread_t thread);
功能: 取消一个线程, 线程号是thread
返回值:
成功, 返回0
失败, 返回-1
#include <pthread.h>
#include <stdio.h>
void * thread1func(void * para)
{
// 线程1 的执行函数
pthread_t i;
i = *(pthread_t*)para;//获取线程号
//printf("thread1 para = %u\n",i);
//允许线程相应cancel, 立即响应
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,0);
while(1)
{
printf("1111111111 thread1 id = %lu\n",i);
sleep(1);
}
}
//线程2的执行体
void *thread2func(void *para)
{
//通过线程2 的创建函数, 可以知道 para 是tid[0] 的地址 , tid数组是pthread_t 类型
pthread_t i,id;
char count=0;
id = *(pthread_t*)para;//===========线程1 的id 号
i = *((pthread_t*)para+1);// =======i是线程2 的id
while(1)
{
printf("2222222222 thread2 id is = %lu\n",i);
sleep(1);
count++;
if(count >= 10) break;
}
pthread_cancel(id);//取消线程1
pthread_exit("thread2 is finished");// 线程2 退出
}
int main()
{
pthread_t tid[2] = {0};//保存线程号
int ret;
char *p=NULL;
char i=0;
//创建线程1, 带回的线程号在tid【0】, 线程1 的执行体是thread1func,&tid[0]就是线程1 的号
ret = pthread_create(&tid[0],NULL,thread1func,&tid[0]);
if(ret == -1)
{
perror("create");
return -1;
}
//创建线程2, 带回的线程号在tid【1】, 线程2 的执行体是thread2func,&tid[0]就是线程1 的号
ret = pthread_create(&tid[1],NULL,thread2func,&tid[0]);
if(ret == -1)
{
perror("create 2");
return -1;
}
printf("********* %lu, %lu *************\n",tid[0],tid[1]);
// 进程执行
while(1)
{
printf("00000000000 process id = %d\n",getpid());
sleep(1);
i++;
if(i >=12)
{
break;
}
}
//回收线程
pthread_join(tid[0],NULL);
pthread_join(tid[1],(void**)&p);
printf("p = %s\n",p);
printf("bye ............\n");
}
二、线程的互斥
1、互斥锁的应用:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mymutex;
unsigned int value1,value2,count=0;
void* thread1fun(void *para)
{
while(1)
{
#ifdef _LOCK_
pthread_mutex_lock(&mymutex);
#endif
if(value1!=value2)
{
printf("in thread ,value1=%u,value2=%u\n",value1,value2);
}
#ifdef _LOCK_
pthread_mutex_unlock(&mymutex);
#endif
usleep(10000);
}
}
int main()
{
pthread_t tid;
#ifdef _LOCK_
pthread_mutex_init(&mymutex,NULL);//初始化🔓
#endif
if(pthread_create(&tid,NULL,thread1fun,NULL)==-1)
{
perror("create");
return -1;
}
while(1)
{
#ifdef _LOCK_
pthread_mutex_lock(&mymutex);
#endif
count++;
value1=count;
value2=count;
#ifdef _LOCK_
pthread_mutex_unlock(&mymutex);
#endif
}
return 0;
}
三、进程间的通信
1、进程之间通信类型
传统的进程间的通信方式: 无名管道,有名管道, 信号
system-v ipc:
共享内存
消息队列 信号量
at&t
贝尔实验室
socket 套接字
----------------------------- bsd
2、实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
char bufw[10]={0};
char bufr[10]={0};
int main()
{
pid_t pid;
int pfd[2]={0};
if(pipe(pfd)==-1)
{
perror("pipe");
return -1;
}
pid=fork();
if(pid==-1)
{
perror("fork");
return -1;
}else if(pid==0)
{
close(pfd[1]);//关闭写文件
while(1)
{
read(pfd[0],bufr,10);//PFD【0】=读
printf("bufr=%s\n",bufr);
if(strncmp(bufr,"quit",4)==0)
{
break;
}
}
exit(0);
}else
{
close(pfd[0]);//关闭读文件
while(1)
{
fgets(bufw,10,stdin);
write(pfd[1],bufw,10);
if(strncmp(bufw,"quit",4)==0)
break;
}
wait();//回收子进程
}
}