是现代操作系统的一个基本概念,是并发程序出现后出现的一个重要概念,它是指程序在一个数据集合上运行的过程,是系统进行资源分配和调度运行的一个独立单位,有时也称为活动、路径或任务。
线程是进程中的一个实体,是进程上下文(context)中执行的代码序列,是被系统调度的基本单元。
线程自己只拥有很少的系统资源(如程序计数器、一组寄存器和栈),但它可与同属一个进程的其他线程共享所属进程所拥有的全部资源,同一进程中的多个线程之间可以并发执行,从而更好地改善了系统资源的利用率。
线程可理解为减负的进程 精干、简单、快速系统在线程间切换比进程间快,得益于线程共享地址空间(代码段、数据段、堆栈)
线程状态:就绪、运行、阻塞、终止 ready running blocked terminated
1、顺序执行的程序
-
-
/*
-
*alarm.c
-
*
-
*Simple synchronous alarm program.Thisisused as a
-
*referenceforprogressive examples of asynchronous
-
*alarm programs.
-
*/
-
#include"errors.h"
-
-
intmain(intargc,char*argv[])
-
{
-
intseconds;
-
char line[128];
-
char message[64];
-
-
while(1){
-
printf("Alarm> ");
-
if(fgets(line,sizeof(line),stdin)==NULL)exit(0);
-
if(strlen(line)<=1)continue;
-
-
/*
-
*Parse input line into seconds(%d)anda message
-
*(%64[^\n]),consisting of upto64 characters
-
*separated from the seconds by whitespace.
-
*/
-
if(sscanf(line,"%d %64[^\n]",
-
&seconds,message)<2){
-
fprintf(stderr,"Bad command\n");
-
}else{
-
sleep(seconds);
-
printf("(%d) %s\n",seconds,message);
-
}
-
}
-
}
-
函数原型:char *fgets(char *buf, int bufsize, FILE *stream);
参数:
*buf: 字符型指针,指向用来存储所得数据的地址。
bufsize: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。
从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize个字符,则读完该行就结束。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。
函数原型:
int sscanf( *, const char *, ...);
int sscanf(const char *buffer,const char *format,[argument ]...);
存储的数据
格式控制字符串
argument 选择性设定字符串
sscanf会从buffer里读进数据,依照format的格式将数据写入到argument里。
采用多线程的方式
-
-
/*
-
*alarm.c
-
*
-
*Simple synchronous alarm program.Thisisused as a
-
*referenceforprogressive examples of asynchronous
-
*alarm programs.
-
*/
-
#include"errors.h"
-
-
intmain(intargc,char*argv[])
-
{
-
intseconds;
-
char line[128];
-
char message[64];
-
-
while(1){
-
printf("Alarm> ");
-
if(fgets(line,sizeof(line),stdin)==NULL)exit(0);
-
if(strlen(line)<=1)continue;
-
-
/*
-
*Parse input line into seconds(%d)anda message
-
*(%64[^\n]),consisting of upto64 characters
-
*separated from the seconds by whitespace.
-
*/
-
if(sscanf(line,"%d %64[^\n]",
-
&seconds,message)<2){
-
fprintf(stderr,"Bad command\n");
-
}else{
-
sleep(seconds);
-
printf("(%d) %s\n",seconds,message);
-
}
-
}
-
}
pthread_create是类Unix操作系统(Unix、Linux、Mac OS X等)的创建线程的函数。
头文件
[1]
函数声明
1
2
|
intpthread_create(pthread_t *thread,constpthread_attr_t *attr,
void*(*start_routine) (void*),void*arg);
|
[1]
编译链接参数
-pthread[1]
返回值
若线程创建成功,则返回0。若线程创建失败,则返回出错编号,并且*thread中的内容是未定义的。[1]
返回成功时,由tidp指向的内存单元被设置为新创建线程的线程ID。attr参数用于指定各种不同的线程属性。新创建的线程从start_rtn函数的地址开始运行,该函数只有一个万能参数arg,如果需要向start_rtn函数传递的参数不止一个,那么需要把这些参数放到一个结构中,然后把这个结构的地址作为arg的参数传入。
linux下用C语言开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。
由 restrict 修饰的是最初唯一对指针所指向的对象进行存取的方法,仅当第二个指针基于第一个时,才能对对象进行存取。对对象的存取都限定于基于由 restrict 修饰的表达式中。 由 restrict 修饰的主要用于函数,或指向由 malloc() 分配的内存空间。restrict 不改变程序的语义。 能通过作出 restrict 修饰的是存取对象的唯一方法的假设,更好地优化某些类型的例程。
参数
第一个参数为指向线程的。
第二个参数用来设置线程属性。
第三个参数是线程运行函数的起始地址。
最后一个参数是运行函数的参数。
注意事项
因为pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。函数在执行错误时的错误信息将作为返回值返回,并不修改系统全局变量errno,当然也无法使用perror()打印错误信息。
阅读(1366) | 评论(0) | 转发(0) |