什么是线程?
线程是进程中的单个序列流。因为线程具有进程的一些属性,所以它们有时被称为轻量级进程。
进程和线程之间有什么区别?
线程不像进程那样彼此独立, 因此线程与其他线程共享它们的代码段, 数据段和OS资源(如打开的文件和信号)。但是, 与进程一样, 线程具有其自己的程序计数器(PC), 寄存器集和堆栈空间。
为什么要使用多线程?
线程是通过并行改进应用程序的流行方法。例如, 在浏览器中, 多个选项卡可以是不同的线程。 MS word使用多个线程, 一个线程格式化文本, 其他线程处理输入, 等等。
由于以下原因, 线程的运行速度比进程快:
1)线程创建要快得多。
2)线程之间的上下文切换要快得多。
3)线程可以轻松终止
4)线程之间的通讯更快。
查看http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm获取更多细节。
我们可以用C编写多线程程序吗?
与Java不同,该语言标准不支持多线程。POSIX Threads(或Pthreads)是用于线程的POSIX标准。pthread的实现可以通过gcc编译器实现。
一个简单的C程序来演示pthread基本功能的使用
请注意, 下面的程序只能使用带有pthread库的C编译器进行编译。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //Header file for sleep(). man 3 sleep for details.
#include <pthread.h>
// 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:~/$
>一个C程序来显示具有全局变量和静态变量的多个线程
如上所述, 所有线程共享数据段。全局变量和静态变量存储在数据段中。因此, 它们被所有线程共享。下面的示例程序进行了演示。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// 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
如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请发表评论。