进程和线程的创建过程

创建进程

在Linux中,创建进程的主要函数是fork(),它会复制当前进程的地址空间、堆、栈、寄存器等资源,创建一个新的子进程。fork()函数没有参数,返回值是一个pid_t类型的整数,表示进程的标识符。如果返回值为0,表示当前是子进程;如果返回值大于0,表示当前是父进程,返回值是子进程的标识符;如果返回值小于0,表示创建进程失败,可以通过errno变量获取错误码。

创建进程后,父进程和子进程的执行顺序是不确定的,取决于操作系统的调度算法。如果想要在父进程中等待子进程结束,可以使用wait()waitpid()函数,它们的参数和返回值如下:

  • wait(int *status):等待任意一个子进程结束,如果没有子进程,返回-1。参数status是一个指针,用于存储子进程的退出状态,可以通过一些宏来判断子进程是正常退出还是异常终止,以及退出码或信号值。返回值是结束的子进程的标识符,或者-1表示出错。
  • waitpid(pid_t pid, int *status, int options):等待指定的子进程结束,或者满足一些条件。参数pid是要等待的子进程的标识符,如果为-1,表示等待任意一个子进程,与wait()相同。参数statuswait()相同,用于存储子进程的退出状态。参数options是一些标志位,用于控制函数的行为,比如是否阻塞等待,是否等待已停止的子进程等。返回值与wait()相同,是结束的子进程的标识符,或者-1表示出错。

下面是一个简单的示例,演示了如何使用fork()wait()函数创建和等待进程:

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;

int main()
{
    cout << "I am the parent process, my pid is " << getpid() << endl;
    pid_t pid = fork(); // create a child process
    if (pid == 0) // child process
    {
        cout << "I am the child process, my pid is " << getpid() << endl;
        sleep(3); // simulate some work
        cout << "I am the child process, I am done" << endl;
        return 0; // exit normally
    }
    else if (pid > 0) // parent process
    {
        cout << "I am the parent process, I created a child process with pid " << pid << endl;
        int status;
        pid_t child_pid = wait(&status); // wait for any child process to end
        if (child_pid == -1)
        {
            perror("wait error");
            return -1;
        }
        if (WIFEXITED(status)) // child process exited normally
        {
            cout << "I am the parent process, my child process " << child_pid << " exited with code " << WEXITSTATUS(status) << endl;
        }
        else // child process terminated abnormally
        {
            cout << "I am the parent process, my child process " << child_pid << " terminated by signal " << WTERMSIG(status) << endl;
        }
        cout << "I am the parent process, I am done" << endl;
        return 0;
    }
    else // fork error
    {
        perror("fork error");
        return -1;
    }
}

输出结果可能是:

I am the parent process, my pid is 1234
I am the parent process, I created a child process with pid 1235
I am the child process, my pid is 1235
I am the child process, I am done
I am the parent process, my child process 1235 exited with code 0
I am the parent process, I am done

创建线程

在Linux中,创建线程的主要函数是pthread_create(),它会在当前进程的地址空间中创建一个新的执行流,与其他线程共享堆、全局变量、静态变量等资源,但有自己的栈、寄存器、程序计数器等。pthread_create()函数的参数和返回值如下:

  • pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg):创建一个新的线程,并让它执行指定的函数。参数thread是一个指针,用于存储新创建的线程的标识符。参数attr是一个属性对象,可以用来设置线程的属性,如栈大小、优先级等,如果使用默认值,可以传入NULL。参数start_routine是一个函数指针,指向线程要执行的函数,该函数的参数和返回值都是void *类型的指针,可以用来传递任意类型的数据。参数arg是传递给线程函数的参数,必须强制转换为void *类型。返回值是一个整数,如果为0,表示创建线程成功,否则表示失败,可以通过errno变量获取错误码。

创建线程后,线程的执行顺序也是不确定的,取决于操作系统的调度算法。如果想要在主线程中等待子线程结束,可以使用pthread_join()函数,它的参数和返回值如下:

  • pthread_join(pthread_t thread, void **retval):等待指定的线程结束,并获取它的返回值。参数thread是要等待的线程的标识符。参数retval是一个指针的指针,用于存储线程函数的返回值,如果不关心返回值,可以传入NULL。返回值是一个整数,如果为0,表示等待线程成功,否则表示失败,可以通过errno变量获取错误码。

下面是一个简单的示例,演示了如何使用pthread_create()pthread_join()函数创建和等待线程:

#include <iostream>
#include <pthread.h>
using namespace std;

// the thread function
void *say_hello(void *args)
{
    cout << "Hello, I am a new thread, my tid is " << pthread_self() << endl;
    return (void *)0; // return normally
}

int main()
{
    cout << "I am the main thread, my pid is " << getpid() << ", my tid is " << pthread_self() << endl;
    pthread_t tid; // the thread identifier
    int ret = pthread_create(&tid, NULL, say_hello, NULL); // create a new thread
    if (ret != 0) // error occurred
    {
        perror("pthread_create error");
        return -1;
    }
    cout << "I am the main thread, I created a new thread with tid " << tid << endl;
    void *retval;
    ret = pthread_join(tid, &retval); // wait for the new thread to end
    if (ret != 0) // error occurred
    {
        perror("pthread_join error");
        return -1;
    }
    cout << "I am the main thread, my new thread ended with retval " << (long)retval << endl;
    return 0;
}

输出结果可能是:

I am the main thread, my pid is 1234, my tid is 140735803338496
I am the main thread, I created a new thread with tid 140735795945216
Hello, I am a new thread, my tid is 140735795945216
I am the main thread, my new thread ended with retval 0
  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值