📜  C语言中的多线程

📅  最后修改于: 2021-05-26 00:31:06             🧑  作者: Mango

什么是线程?
线程是流程中的单个序列流。因为线程具有进程的某些属性,所以有时将它们称为轻量级进程

进程和线程之间有什么区别?
线程不像进程那样彼此独立,因此线程与其他线程共享它们的代码段,数据段和OS资源(如打开的文件和信号)。但是,与进程一样,线程具有其自己的程序计数器(PC),寄存器集和堆栈空间。

为什么要使用多线程?
线程是通过并行改进应用程序的流行方法。例如,在浏览器中,多个选项卡可以是不同的线程。 MS word使用多个线程,一个线程格式化文本,其他线程处理输入,等等。
由于以下原因,线程的运行速度比进程快:
1)线程创建要快得多。
2)线程之间的上下文切换要快得多。
3)线程可以轻松终止
4)线程之间的通信速度更快。

有关更多详细信息,请参见http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm。

我们可以用C编写多线程程序吗?
与Java不同,语言标准不支持多线程。 POSIX线程(或Pthreads)是线程的POSIX标准。 gthread编译器提供了pthread的实现。

一个简单的C程序来演示pthread基本功能的使用
请注意,下面的程序只能使用带有pthread库的C编译器进行编译。

#include 
#include 
#include   //Header file for sleep(). man 3 sleep for details.
#include 
  
// A normal C function that is executed as a thread 
// when its name is specified in pthread_create()
void *myThreadFun(void *vargp)
{
    sleep(1);
    printf("Printing GeeksQuiz from Thread \n");
    return NULL;
}
   
int main()
{
    pthread_t thread_id;
    printf("Before Thread\n");
    pthread_create(&thread_id, NULL, myThreadFun, NULL);
    pthread_join(thread_id, NULL);
    printf("After Thread\n");
    exit(0);
}

在main()中,我们声明了一个名为thread_id的变量,其类型为pthread_t,它是用于标识系统中线程的整数。声明thread_id之后,我们调用pthread_create()函数创建一个线程。
pthread_create()接受4个参数。
第一个参数是此函数设置的指向thread_id的指针。
第二个参数指定属性。如果该值为NULL,则应使用默认属性。
第三个参数是要创建的线程要执行的函数的名称。
第四个参数用于将参数传递给函数myThreadFun。
线程的pthread_join()函数等效于进程的wait()。对pthread_join的调用将阻塞调用线程,直到标识符等于第一个参数的线程终止。

如何编译以上程序?
要使用gcc编译多线程程序,我们需要将其与pthreads库链接。以下是用于编译程序的命令。

gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Before Thread
Printing GeeksQuiz from Thread 
After Thread
gfg@ubuntu:~/$ 

AC程序显示具有全局变量和静态变量的多个线程
如上所述,所有线程共享数据段。全局变量和静态变量存储在数据段中。因此,它们被所有线程共享。下面的示例程序进行了演示。

#include 
#include 
#include 
#include 
  
// Let us create a global variable to change it in threads
int g = 0;
  
// The function to be executed by all threads
void *myThreadFun(void *vargp)
{
    // Store the value argument passed to this thread
    int *myid = (int *)vargp;
  
    // Let us create a static variable to observe its changes
    static int s = 0;
  
    // Change static and global variables
    ++s; ++g;
  
    // Print the argument, static and global variables
    printf("Thread ID: %d, Static: %d, Global: %d\n", *myid, ++s, ++g);
}
  
int main()
{
    int i;
    pthread_t tid;
  
    // Let us create three threads
    for (i = 0; i < 3; i++)
        pthread_create(&tid, NULL, myThreadFun, (void *)&tid);
  
    pthread_exit(NULL);
    return 0;
}
gfg@ubuntu:~/$ gcc multithread.c -lpthread
gfg@ubuntu:~/$ ./a.out
Thread ID: 3, Static: 2, Global: 2
Thread ID: 3, Static: 4, Global: 4
Thread ID: 3, Static: 6, Global: 6
gfg@ubuntu:~/$ 

请注意,以上是显示线程如何工作的简单示例。在线程中访问全局变量通常不是一个好主意。如果线程2优先于线程1并且线程1需要更改变量,该怎么办。实际上,如果需要多个线程访问全局变量,则应使用互斥锁对其进行访问。

参考:
http://www.csc.villanova.edu/~mdamian/threads/posixthreads.html
计算机系统:程序员

想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。