POSIX线程编程

死在山野的风里,活在自由的梦里
本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册(含学习通的一些程序笔记)。

POSIX线程编程

    • 1.线程是什么
    • 2.创建线程
      • 创建一个用户级的线程,实现在线程中更改进程(主线程)中的数据并输出验证修改结果。26-2.c
      • 利用多线程实现单词统计,即通过命令行参数指定多个文件给程序统计其中的单词数,程序采用为每一个文件创建一个线程来统计其单词数。

1.线程是什么

是一个程序内可被操作系统调用的,可以并发运行的任务

用于同时监控一个程序里面的多个并发的任务

(如果用父子进程也能同时监控,但是是用不同进程去监控的)

切换时开销更小

2.创建线程

创建一个用户级的线程,实现在线程中更改进程(主线程)中的数据并输出验证修改结果。26-2.c

#include
#include
#include
#include

static int i = 1;
//i是全局变量

void *create(void *arg)	
{	//函数名前加*,说明返回的是一个指向函数的指针
   printf("new pthread ...\n");
   printf("shared data = %d\n",i);
   printf("my tid is %ld\n",(unsigned long int)pthread_self());
   //在线程中通过pthread_self()函数返回自己的pid,类型为无符号长整数(unsigned long int),在printf中用%ld格式化输出。
   i=2;
   //修改全局变量i的值
   return (void *)0;
}

int main()
{
   pthread_t l;
   //l用来存储线程的tid,数据类型pthread_t是无符号长整数(unsigned long int)
   i=3;
   //修改全局变量i的值	
   if(pthread_create(&l,NULL,create,NULL))
   {	//pthread_create()函数需要四个参数,其中第一个是存线程tid的地址&l,并且会向l返回所创建线程的tid,第三个变量是线程程序的起始地址,即指向线程程序的指针
   	//pthread_create()函数成功则返回0,否则返回出错编号
   	printf("create pthread failed\n");
   	return -1;
   }
   else
   {
   	sleep(1);
   	printf("create pthread successfully\n");
   	printf("And shared data = %d\n return tid = %ld\n",i,(unsigned long int)l);
   	//输出main中i的值以及pthread_create()函数所创建线程的ID——l的值
   	return 0;
   }
   int n = sizeof(pthread_t);
   printf("the pthread_t has %d Byte\n",n);

}

POSIX线程编程_第1张图片
完成利用多线程实现单词统计的实验(参考教科书P264例子)。

利用多线程实现单词统计,即通过命令行参数指定多个文件给程序统计其中的单词数,程序采用为每一个文件创建一个线程来统计其单词数。

提示:可以包含ctype.h文件,利用isalnum(int c)函数判断字符变量c是否为数字或字母,是则返回真(非零)。

#include 
#include 
#include 
#include 
#include 
#include 

int aaa(char filename[256])
{
    char ch;
    int wordStart = 0, sum = 0; // sum单词总数
    int i = 0, j = 0;
    char copy[20] = ""; //暂存读取的一个完整单词
    FILE *fp = NULL;

    fp = fopen(filename, "r");
    if (fp == NULL)
    {
        printf("文件打开出错了!");
        exit(0);
    }
    //读取文件内容
    while (!feof(fp))
    {
        ch = fgetc(fp);
        if (isalpha(ch)) //单词开始
        {
            wordStart = 1;  //标记
            copy[i++] = ch; //把一个完整单词每个字符依次存进copy
        }
        else if (!isalpha(ch) && wordStart == 1) //判断一个单词结束
        {
            sum++; //单词总个数+1
            //必须要这两个,不然会把别的字符也当成单词
            wordStart = 0;     
            i = 0;
            
            for (j = 0; j < 20; j++) //一个单词结束,copy清空
            {
                fflush(stdout);
            }
        }
    }
    printf("%s 总单词数为 %d \n", filename, sum);
    return sum;
}

int count[30] = {0};       //文件单词数初始值都是0
pthread_mutex_t fileMutex; //定义一个互斥变量
int main(int argc, char **argv)
{
    int i = 0;
    int flag; //如果输入命令格式不正确,应该给出提示
    if (argc < 2)
    {
        printf("./xx 1.txt 2.txt");
        exit(0);
    }
    *argv++; // +1
    pthread_t thread[argc - 1];

    /*互斥锁初始化*/
    flag = pthread_mutex_init(&fileMutex, NULL);
    if (flag != 0)
    {
        perror("出错了\n");
        return 1;
    }
    for (i = 0; i < argc - 1; i++)
    {
        flag = pthread_create(&thread[i], NULL, (void *)aaa, *argv++);
        if (flag != 0)
            return 1;
    }
    for (i = 0; i < argc - 1; i++)
        pthread_join(thread[i], (void **)&count[i]);

    int sum = 0;
    for (i = 0; i < 30; i++)
        sum += count[i];
    printf("总单词数量 %d", sum);
    return 0;
}

POSIX线程编程_第2张图片
POSIX线程编程_第3张图片

你可能感兴趣的:(linux实验,linux,c#,信息与通信)