线程与进程

 

线程的创建与终止

pthread_create()可以创建线程,其代码如下:

void *thread_function(void *index)
e = pthread_create(
    pthread_t *thread_id,
    const pthread_attr_t *attr,
    thread_function,
    void *index
);


线程的连接

pthread_join()函数功能为等待指定线程结束,其放在主线程中目的是等待子线程结束,主线程再继续运行,其代码如下:

pthread_join(pthread_t thread, void **retval)

 


属性对象的初始化与销毁

pthread_attr_init()函数用于对线程属性对象的初始化,线程具有属性,在对该结构进行处理之前必须进行初始化,其代码如下

int pthread_attr_init(pthread_attr_t *attr);


互斥锁静态与动态初始化及销毁

互斥锁可用于使线程按顺序进行,其中互斥锁的初始化用到pthread_mutex_t mutex以及int pthread_mutex_init()函数,前者可静态初始化互斥锁,后者可动态初始化互斥锁

PTHREAD_MUTEX_INITIALIZER为一结构常量
restrict mutex为新建的互斥锁变量
restrict attr指定了新建互斥锁的属性
互斥锁的销毁意味着释放它所占用的资源,且要求锁当前处于开放状态。需要用到pthread_mutex_destroy()函数

互斥锁加锁与解锁

互斥锁可用来保护多个线程共享的数据和结构不会被他人修改,一个互斥锁只能有两个状态,即加锁和解锁状态,所用到pthread_mutex_lock()和pthread_mutex_unlock()函数。加锁可使其不被其他线程访问,只能由一个线程掌握,解锁即解除加锁的互斥锁,而这所用到的代码如下:

 

int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);

进程的创建

进程的创建需要用到fork()函数,其作用是创建父子进程,且父子进程二者的进程号不一致,即二者分别走向不同的方向,互不干扰。且fork()函数的返回值有两个,第一个为父进程的进程号,第二个的返回值为0,是子进程返回的,若返回值为-1,则表明进程创建失败。

进程的等待

进程等待用到wait()函数,进程一旦调用了wait()函数,该进程就会立刻阻塞,暂停运行,直至找到一个已经变为僵尸进程的子进程出现,wait()函数会收集这个子进程的信息,销毁后返回,都则会一直阻塞进程,其代码如下:

int wait(int* statloc);

编译

/*  线程的创建与终止 :  */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5

void *thread_function(void *index) { /* 线程函数 */
    long tid;
    tid = (long) index;
    printf("Hello World! This is thread #%ld!\n", tid); /* 打印线程对应的参数 */
    pthread_exit(NULL);    /* 退出线程 */
}

int main(int argc, char *argv[]) {
    pthread_t tid_array[NUM_THREADS];
    int returned_code_err;
    long index;
    for (index = 0; index < NUM_THREADS; index++) { /* 循环创建 5 个线程 */
        printf("In main: creating thread %ld.\n", index);
        returned_code_err = pthread_create(
            &tid_array[index], 
            NULL, 
            thread_function, 
            (void *) index
        ); /* 创建线程 */
        if (returned_code_err) {
            printf("ERR: return code from pthread_create() is not 0, but %d\n", returned_code_err);
            exit(-1);
        }
    }
    printf("Main exits.\n");
    pthread_exit(NULL); /* 主线程退出 */
    return 0;
}


运行结果

S
./1. pthread_create_exit.out
In main: creating thread o.
In main: creating thread 1.
Hello World! This is thread #0!
In main: creating thread 2.
In main: creating thread 3
Hello World! This is thread #2!
In main: creating thread 4.
Main exits.
Hello World! This is thread #1!
Hello World! This is thread #3!
'Hello World! This is thread #4|

线程的连接

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS 4

void *thread_func(void *index) { /* 线程函数 */
    int i;
    long tid;
    double result=0.0;
    tid = (long)index;
    printf("Thread %ld starting...\n",tid);

    for (i=0; i<1000000; i++) {
        result = result + sin(i) * tan(i); /* 进行数学运算 */
    }
    printf("Thread %ld done. Result = %e\n",tid, result);
    pthread_exit((void*) index); /* 带计算结果退出 */
}


int main (int argc, char *argv[]) {
    pthread_t tid_array[NUM_THREADS];
    int err;
    long index;
    void *status;

    for(index=0; index<NUM_THREADS; index++) {
        printf("Main: creating tid_array %ld\n", index);
        err = pthread_create(
            &tid_array[index], 
            NULL, 
            thread_func, 
            (void *)index
        ); /* 创建线程 */
        if (err) {
            printf("ERROR; return code from pthread_create() is %d\n", err);
            exit(-1);
        }
    }

    for(index=0; index<NUM_THREADS; index++) {
        err = pthread_join(
            tid_array[index], 
            &status
        ); /*等待线程终止,并获取返回值*/
        if (err) {
            printf("ERROR; return code from pthread_join() is %d\n", err);
            exit(-1);
        }
        printf("Main: completed join with tid_array %ld having a status of %ld\n",index,(long)status);
    }

    printf("Main: program completed. Exiting.\n");
    pthread_exit(NULL);
}

 


属性对象的初始化与销毁

#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>

#define handle_error_en(en, msg) do {errno = en; perror(msg); exit(EXIT_FAILURE);}while (0)
#define handle_error(msg) do {perror(msg); exit(EXIT_FAILURE);}while (0)

struct thread_info {
    pthread_t thread_id;
    int thread_num;
    char *argv_string;
};

static void *thread_func(void *arg) { /* 线程运行函数 */
    struct thread_info *thread_info_struct_array = arg;
    char *uargv, *p;
    printf("Thread %d: top of stack near %p; argv_string=%s\n", /* 通过 p 的地址来计算栈的起始地址*/
    thread_info_struct_array->thread_num, &p, thread_info_struct_array->argv_string);

    uargv = strdup(thread_info_struct_array->argv_string);
    if (uargv == NULL)
        handle_error("strdup");
    for (p = uargv; *p != '\0'; p++)
        *p = toupper(*p); /* 小写字符转换大写字符 */

    return uargv; /* 将转换结果返回 */
}

int main(int argc, char *argv[]) {
    int s, index, opt, num_threads;
    struct thread_info *thread_info_struct_array;
    pthread_attr_t attr_struct;
    int stack_size;
    void *res;
    stack_size = -1;

    /* 处理参数 -s 所指定的栈大小 */
    while ((opt = getopt(argc, argv, "s:")) != -1) { 
        switch (opt) {
        case 's':
            stack_size = strtoul(optarg, NULL, 0); // string to unsigned long
            break;
        default:
            fprintf(stderr, "Usage: %s [-s stack-size] arg...\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    num_threads = argc - optind;
    
    /* 初始化属性对象 */
    s = pthread_attr_init(&attr_struct);
    
    if (s != 0)
        handle_error_en(s, "pthread_attr_init");

    if (stack_size > 0) {
        /* 设置属性对象的栈大小 为 用户命令行参数 -s 指定值 */
        s = pthread_attr_setstacksize(
            &attr_struct, 
            stack_size
        );
        if (s != 0)
            handle_error_en(s, "pthread_attr_setstacksize");
    }
    thread_info_struct_array = calloc(num_threads, sizeof(struct thread_info));

    if (thread_info_struct_array == NULL)
        handle_error("calloc");

    for (index = 0; index < num_threads; index++) {
        thread_info_struct_array[index].thread_num = index + 1;
        thread_info_struct_array[index].argv_string = argv[optind + index];
        s = pthread_create(
            &thread_info_struct_array[index].thread_id, 
            &attr_struct, /* 根据属性创建线程 */
            &thread_func, 
            &thread_info_struct_array[index]
        );
        if (s != 0)
            handle_error_en(s, "pthread_create");
    }

    /* 销毁属性对象 */
    s = pthread_attr_destroy(&attr_struct);
    
    if (s != 0)
        handle_error_en(s, "pthread_attr_destroy");

    for (index = 0; index < num_threads; index++) {
        s = pthread_join(thread_info_struct_array[index].thread_id, &res); /* 等待线程终止,并获取返回值 */
        if (s != 0)
            handle_error_en(s, "pthread_join");

        printf("Joined with thread %d; returned value was %s\n",
                thread_info_struct_array[index].thread_num, (char *) res);
        free(res);
    }

    free(thread_info_struct_array);
    exit(EXIT_SUCCESS);
}

条件变量

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>

pthread_t tid_array[3];
int sum = 0;
pthread_mutex_t sum_lock = PTHREAD_MUTEX_INITIALIZER;   /* 互斥量 (静态初始化)*/
pthread_cond_t condition_sum_ready = PTHREAD_COND_INITIALIZER;                         /* 条件量 (静态初始化) */

void * worker_thread_func(void *arg) {
    int i;
    long id = (long) arg;
    for (i = 0; i < 60; i++) {
        pthread_mutex_lock(&sum_lock);                 /* 使用互斥量保护临界变量 */
        printf("t%ld: read sum value before = %d\n", id + 1, sum);
        sum++;
        printf("t%ld: read sum value after  = %d\n", id + 1, sum);
        pthread_mutex_unlock(&sum_lock);               /* 结束互斥量保护临界变量 */
        if (sum >= 100)
            pthread_cond_signal(&condition_sum_ready);                                  /* 通过条件量 发送条件通知 -> 唤醒等待线程 */
    }
    return NULL;
}

void * waiting_thread_func(void *arg) {
    long id = (long) arg;
    pthread_mutex_lock(&sum_lock);
    while (sum < 100)                                                                 /* 不满足条件将一直等待 */
        pthread_cond_wait(&condition_sum_ready, &sum_lock);                         /* 通过条件量 等待条件通知 -> 唤醒等待线程 */
    sum = 0;
    printf("waiting_thread_func: clear sum value [我是等待线程,已被唤醒。 ]\n");
    printf("t%ld: read sum value = %d\n", id + 1, sum);
    pthread_mutex_unlock(&sum_lock);
    return NULL;
}

int main(void) {
    int err;
    long i;
    for (i = 0; i < 2; i++) {
        err = pthread_create(&(tid_array[i]), NULL, &worker_thread_func, (void *) i);         /* 创建线程 1 线程 2 */
        if (err != 0) {
            printf("Can't create thread :[%s]", strerror(err));
        }
    }
    
    err = pthread_create(&(tid_array[2]), NULL, &waiting_thread_func, (void *) i);            /* 创建线程 3 */
    if (err != 0)
        printf("Can't create thread :[%s]", strerror(err));
    for (i = 0; i < 3; i++)
        pthread_join(tid_array[i], NULL);
    
    return 0;
}

 

运行开发板

~/ubuntu-18.04_imx6ul_qemu_system/gui-qemu-imx6ull-gui.sh 

使用开发板

fb-test
myfb-test /dev/fb0

命令控制LED

cd ~/led_driver_qemu/
insmod 100ask_led.ko
./ledtest /dev/100ask_led0 on
./ledtest /dev/100ask_led1 on
./ledtest /dev/100ask_led2 on

按键控制LED 

cd ~/button_driver_qemu/
insmod button_drv.ko
insmod board_100ask_qemu_imx6u
./button_led_test

 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETkBCYXppbmdhX2xr,size_20,color_FFFFFF,t_70,g_se,x_16

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值