进程:
优点:多个进程并发执行,能够参与系统调度,是资源管理和程序执行的最小单位。
缺点:占用资源(无论哪种通信方式都需要创建第三方),效率低下(每次对数据的访问都需经过第三方),系统开销大(进程退出需要保存,执行需要加载资源)。
线程:
优点:多个线程并发执行--à系统调度的最小单位。
与进程共享资源。
同一进程中创建的线程共享进程地址空间。
Linux中使用task_struct来描述一个线程。
一个进程中的多线程可以共享以下资源:
可执行的指令
静态数据
进程中打开的文件描述符
信号处理函数
当前工作目录
用户ID
用户组ID
堆空间要共享可将其指针声明为全局变量,函数中再为其分配空间。
栈区是私有的,也就是局部变量。
线程的相关操作:
线程的创建:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
thread:线程id
attr:线程属性 NULL为默认属性。
routine:线程执行的函数
arg:传递给线程执行的参数
等待线程退出:
int pthread_join(pthread_t thread, void **retval);
Retval:用于捕获线程的退出信息==waitpid()捕获exit的退出编号
线程退出:
void pthread_exit(void *retval);
retval==”pthread is out”;可以填NULL
取消线程:一个线程通知另一个线程退出;
int pthread_cancel(pthread_t thread);
thread:要取消的线程。
范例:
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct messages
{
int a;
int b;
};
void *hello(void *s)
{
struct messages s1=*(struct messages *)s;
printf("the sturct messages s__a=%d ",s1.a);
printf("the sturct messages s__b=%d ",s1.b);
}
int main()
{
struct messages test;
pthread_t thread_id;
test.a=33;
test.b=44;
pthread_create(&thread_id,NULL,hello,(void *)&test);
printf("the new thread id is %u ",thread_id);
pthread_join(thread_id,NULL);
}
char message[32] = "Hello World";
void *thread_function(void *arg);
pthread_exit() pthrad_join()范例:
int main(int argc, char *argv[])
{
pthread_t a_thread;
void *thread_result;
if (pthread_create(&a_thread, NULL, thread_function, (void *)message) < 0)
/*使用缺省属性创建线程*/
{
perror("fail to pthread_create");
exit(-1);
}
printf("waiting for thread to finish ");
if (pthread_join(a_thread, &thread_result) < 0) // 等待线程结束
{
perror("fail to pthread_join");
exit(-1);
}
printf("MESSAGE is now %s ", message);
printf("pthread eixt message is %s ",thread_result);
return 0;
}
void *thread_function(void *arg)
{
printf("thread_function is running, argument is %s ", (char *)arg);
strcpy(message, "marked by thread");
pthread_exit("Thank you for the cpu time");
}
Pthread_cancel()范例:
void *thread_function(void *arg);
int main()
{
int res;
pthread_t a_thread;
res =pthread_create(&a_thread,NULL,thread_function,NULL);
if(res!=0)
{
perror("thread failed");
exit(-1);
}
sleep(5);
printf("cancelling thread.... ");
res = pthread_cancel(a_thread);
if(res!=0)
{
perror("thread failed");
exit(-1);
}
printf("wainting for thread ");
res = pthread_join(a_thread,NULL);
if(res!=0)
{
perror("thread join failed");
exit(-1);
}
exit(0);
}
void *thread_function (void *arg)
{
int i;
for(i=0;i<9;i++)
{printf("thread is running(%d)... ",i);
sleep(1);
}
pthread_exit(0);
}
线程的执行顺序的控制:
互斥锁:
用于操作共享资源:先判断锁的状态,如果已解锁,先上锁,在操作。操作完解锁
如果已上锁则会阻塞;
- 互斥锁初始化:
int pthread_mutex_destroy(pthread_mutex_t *mutex); //销毁锁
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);//初始化锁
锁上,阻塞线程:谁上锁,谁解锁。
int pthread_mutex_lock(pthread_mutex_t *mutex);//先查看锁的状态,如果未解锁,阻塞
int pthread_mutex_trylock(pthread_mutex_t *mutex);上锁不阻塞。
int pthread_mutex_unlock(pthread_mutex_t *mutex);//查看锁的状态,为上锁则阻塞。
互斥锁范例:特别经典(注意锁的走向)
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#include<semaphore.h>
#include<string.h>
#define WORK_SIZE 1024
void * thread_function(void *arg);
pthread_mutex_t work_mutex;
char work_area[WORK_SIZE];
int time_to_exit =0;
int main(int argc,char *argv[])
{
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_mutex_init(&work_mutex,NULL);
if(res !=0)
{
printf("mutex initialization failed ");
exit(-1);
}
res = pthread_create(&a_thread,NULL,thread_function,NULL);
if(res !=0)
{
printf("thread create failed ");
exit(-1);
}
pthread_mutex_lock(&work_mutex);
printf("input some text,enter 'end' to finish ");
while(!time_to_exit)
{
fgets(work_area,WORK_SIZE,stdin);
pthread_mutex_unlock(&work_mutex);
while(1)
{
pthread_mutex_lock(&work_mutex);
if(work_area[0]!=' ')
{
pthread_mutex_unlock(&work_mutex);
sleep(1);
}
else
break;
}
}
pthread_mutex_unlock(&work_mutex);
printf("waiting for thread to finish... ");
res = pthread_join(a_thread,&thread_result);
if(res !=0)
{
printf("thread join failed ");
exit(-1);
}
printf("thread join ");
pthread_mutex_destroy(&work_mutex);
exit(-1);
}
void *thread_function(void *arg)
{
pthread_mutex_lock(&work_mutex);
while(strncmp("end",work_area,3)!=0)
{
printf("you input %d charactes ",strlen(work_area)-1);
printf("the characters is %s",work_area);
work_area[0]=' ';
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
while(work_area[0]==' ')
{
pthread_mutex_unlock(&work_mutex);
sleep(1);
pthread_mutex_lock(&work_mutex);
}
}
time_to_exit=1;
work_area[0]=' ';
pthread_mutex_unlock(&work_mutex);
pthread_exit(0);
}
条件变量:
创建条件变量:
int pthread_cond_destroy(pthread_cond_t *cond);//销毁
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//初始化
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
条件阻塞:接收到条件变量的信号则退出阻塞状态
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
发送条件变量:
int pthread_cond_broadcast(pthread_cond_t *cond);//给所有的线程广播信号,让阻塞的线程退出阻塞。
int pthread_cond_signal(pthread_cond_t *cond);给单个线程发送信号,退出阻塞。
条件变量必须和互斥锁搭配使用
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a,b;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *f1(void *p)
{
pthread_mutex_lock(&mutex);
printf("a = %d,b=%d ",a,b);
printf("hello ");
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);//需要读完了数据才发送信号。
}
int main()
{
a = 2;
b = 10;
pthread_t pthreadid;
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
pthread_create(&pthreadid,NULL,f1,NULL);
while(1)
{
pthread_mutex_lock(&mutex);
printf("a = %d,b=%d ",a,b);
a++;
b--;
if(a == b)
{pthread_cond_wait(&cond,&mutex);//只有锁住了才会有阻塞,wait才能有用
exit(0);
}
pthread_mutex_unlock(&mutex);
}
}