特殊的进程
线程是任务执行的最小单位
多线程公用一片进程空间
多线程共享的数据:
指令
静态数据
文件描述符
用户ID
用户组ID
工作目录
信号处理函数
多线程不共享的数据:
堆栈(栈空间)
程序计数器
线程ID
线程属性(状态、优先级)
错误号
信号掩码
线程相关函数调用(第三方库函数)
线程创建
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
返回值:成功返回0,失败为非0
thread:存储线程ID的地址
attr:创建时的属性
start_routine:线程执行函数的入口地址
arg:传递给线程执行函数的参数
线程回收
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
功能:阻塞等待线程,回收其资源
返回值:成功0,失败非0
thread:线程id
retval:线程结束时留下的信息
线程退出
#include <pthread.h>
void pthread_exit(void *retval);
功能:主动退出线程(当前线程退出)
retval:留下的信息
线程分离
#include <pthread.h>
int pthread_detach(pthread_t thread);
功能:分离线程,线程退出时不需要回收,由系统回收。
threa:线程id
线程取消
#include <pthread.h>
int pthread_cancel(pthread_t thread);
功能:线程取消,取决于其状态与属性
thread:线程id
线程间通信
同一线程下的不同线程都共享同一片内存空间。线程又是以函数为执行单位,使用全局变量通信最为方便
需要添加同步互斥机制
互斥锁
保护某一段代码(临界资源),互斥锁本身是系统中的一种资源,
如要使用互斥锁保护的代码,需要向系统申请资源
定义互斥锁
pthread_mutex_t mutex;//互斥锁变量类型
初始化锁资源
int pthread_mutex_init (pthread_mutex_t* mutex, pthread_mutexattr_t * attr);
功能:锁资源的初始化,在系统中定义出来的一种锁,并且初始化这个锁的个数为1
返回值:成功为0
mutex:锁对象,存储锁的地址
mutexattr:锁的属性,默认属性传入NULL
申请锁(加锁)
int pthread_mutex_lock(pthread_mutex_t* mutex);
功能:向系统申请参数列表中的锁资源,如果系统中有这个资源,那么代码可以继续往后执行,
并且这种资源的个数-1。若没有,代码会阻塞等待。
mutex:要申请的锁资源
释放锁(解锁)
int pthread_mutex_unlock(pthread_mutex_t* mutex);
功能:向系统中释放一种资源,使数目+1
摧毁锁
int pthread_mutex_destory(pthread_mutex_t* mutex);
功能:释放动态初始化的互斥锁变量,防止内存泄漏
信号量
也是系统中的一种资源,可以有多个,实现同步进制。
头文件
#include <semaphore.h>
定义
sem_t sem;//变量类型
信号量初始化
int sem_init(sem_t *sem, int pshared, unsigned int value);
功能:向系统中声明一种信号量资源,这种资源可以有多个,方便P/V操作
返回值:成功0,失败-1
sem:信号量对象,存储信号量的地址
pshared:0表示线程共用,非0表示进程之间共用
value:信号量初始化个数
请求信号量
int sem_wait(sem_t *sem);
功能:申请系统中的信号量资源,若能够申请到,并且信号量-1。若没有信号量,则阻塞等待。
返回值:成功0,失败-1
sem:信号量对象
释放信号量
int sem_post(sem_t *sem);
功能:向系统中释放一种信号量资源,使数目+1
返回值:成功0,失败-1
sem:信号量对象
摧毁信号量
int sem_destroy(sem_t *sem);
功能:释放动态初始化的信号量变量,防止内存泄漏
部分代码示例
//线程的创建
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
void *func01(void *a)
{
int *o=(int *)a;
int *p=(int *)a;
while(1)
{
printf("pthread01:%d\n",*p);
if(p==o+9)
{
p=a;
}
p++;
sleep(1);
}
}
void *func02(void *a)
{
int *o=(int *)a;
int *p=(int *)a+9;
while(1)
{
printf("pthread02:%d\n",*p);
if(p==o)
{
p=o+9;
}
p--;
sleep(1);
}
}
int main(int argc, char *argv[])
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int *q=arr;
q=(void *)q;
void *(*p)(void *)=func01;
pthread_t pid;
pthread_create(&pid,NULL,p,q);
p=func02;
pthread_create(&pid,NULL,p,q);
while(1);
}
//等待子线程结束
#include <stdio.h>
#include <pthread.h>
void *fun01(void *arg)
{
printf("Im child\n");
pthread_exit("bye bye");
}
int main(int argc, char *argv[])
{
pthread_t id;
pthread_create(&id,NULL,fun01,NULL);
printf("Im parent\n");
char *ret;
pthread_join(id,(void**)&ret);
printf("child say %s\n",ret);
printf("parent say over\n");
return 0;
}
//互斥锁
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int a[2]={2,2};
pthread_mutex_t mutex;
void *func01(void *arg)
{
//int *p=(int *)arg;
while(1)
{
pthread_mutex_lock(&mutex);
if(a[0]==a[1])
{
printf("child: %d equal %d\n",a[0],a[1]);
}
else
{
printf("child: %d unequal %d\n",a[0],a[1]);
}
pthread_mutex_unlock(&mutex);
sleep(1);
}
}
int main(int argc, char *argv[])
{
pthread_t id;
pthread_create(&id,NULL,func01,(void *)a);
pthread_mutex_init(&mutex,NULL);
while(1)
{
pthread_mutex_lock(&mutex);
a[0]++;
a[1]++;
pthread_mutex_unlock(&mutex);
//sleep(1);
}
return 0;
}
//信号量
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t semr,semw;
char buf[64];
void *func(void *arg)
{
while(1)
{
sem_wait(&semr);
printf("%s\n",buf);
sem_post(&semw);
}
}
int main(int argc, char *argv[])
{
pthread_t id;
pthread_create(&id,NULL,func,NULL);
sem_init(&semr,0,0);
sem_init(&semw,0,1);
while(1)
{
sem_wait(&semw);
fgets(buf,sizeof(buf),stdin);
sem_post(&semr);
}
return 0;
}
//信号量实现互斥锁
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
sem_t sem;
void *func(void *arg)
{
while(1)
{
sem_wait(&sem);
printf("Im child pthread\n");
sem_post(&sem);
sleep(1);
}
}
int main(int argc, char *argv[])
{
pthread_t pth;
pthread_create(&pth,NULL,func,NULL);
sem_init(&sem,0,1);
while(1)
{
sem_wait(&sem);
printf("Im main pthread\n");
sem_post(&sem);
sleep(1);
}
}