我正在尝试使用clone()创建一个新线程.使用以下代码(…):

#include

#include

#include

#define _SCHED_H 1

#define __USE_GNU 1

#include

#define STACK_SIZE 4096

int func(void *arg) {

printf("Inside func.\n");

sleep(1);

printf("Terminating func...\n");

return 0;

}

int main() {

printf("This process pid: %u\n", getpid());

char status_file[] = "/proc/self/status";

void *child_stack = malloc(STACK_SIZE);

int thread_pid;

printf("Creating new thread...\n");

thread_pid = clone(&func, child_stack+STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES, NULL);

printf("Done! Thread pid: %d\n", thread_pid);

FILE *fp = fopen(status_file, "rb");

printf("Looking into %s...\n", status_file);

while(1) {

char ch = fgetc(fp);

if(feof(fp)) break;

printf("%c", ch);

}

fclose(fp);

getchar();

return 0;

}

我得到以下内容:

This process pid: 10839

Creating new thread...

Done! Thread pid: 10840

Inside func.

Looking into /proc/self/status...

Name: threadTest02

State: R (running)

Tgid: 10839

Pid: 10839

PPid: 4777

TracerPid: 0

Uid: 1000 1000 1000 1000

Gid: 1000 1000 1000 1000

FDSize: 256

Groups: 4 20 24 27 30 46 107 123 124 1000

VmPeak: 4300 kB

VmSize: 4300 kB

VmLck: 0 kB

VmPin: 0 kB

VmHWM: 356 kB

VmRSS: 356 kB

VmData: 188 kB

VmStk: 136 kB

VmExe: 4 kB

VmLib: 1884 kB

VmPTE: 32 kB

VmSwap: 0 kB

Threads: 1

SigQ: 0/22869

SigPnd: 0000000000000000

ShdPnd: 0000000000000000

SigBlk: 0000000000000000

SigIgn: 0000000000000000

SigCgt: 0000000000000000

CapInh: 0000000000000000

CapPrm: 0000000000000000

CapEff: 0000000000000000

CapBnd: ffffffffffffffff

Cpus_allowed: 3

Cpus_allowed_list: 0-1

Mems_allowed: 00000000,00000001

Mems_allowed_list: 0

voluntary_ctxt_switches: 1

nonvoluntary_ctxt_switches: 1

Terminating func...

那么,简而言之,我的计划做了什么?它使用clone创建一个新线程并打印其/ proc / self / status,以便我可以看到它的状态.由于我的线程休眠1秒,因此在打印/ proc / self / status时它仍处于活动状态.

但是,至少有两件事使我的线程不像普通线程.首先,正如您在上面看到的,进程’pid是10839而我的线程的pid是10840.因此,进程和我的线程没有相同的pid,就像在一个共同的线程中一样.其次,即使在我的线程创建之后,我的进程’/ proc / self / status文件的Threads:字段仍然是1.所以,我的线程似乎不被识别为线程.

我的问题是,我的代码中缺少什么?我需要做些什么才能使我的线程像普通线程一样?克隆的第三个参数中是否缺少任何选项?

解决方法:

您可能希望看到标志CLONE_THREAD,它会将新线程放在与调用进程相同的线程组中.

一旦你给了CLONE_THREAD,它将使新线程与调用进程具有相同的pid和ppid.它用于posix线程.以下是我系统的输出. LWP专栏说这是一个轻量级的过程,具有不同的TID

UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD

anukalp 18398 9638 18398 0 2 464 456 0 10:56 pts/3 00:00:00 ./a.out

anukalp 18398 9638 18399 0 2 464 456 1 10:56 pts/3 00:00:00 ./a.out

此外,/ proc / self / status的输出发生了变化,我添加了几个printfs:

[anukalp @ localhost~] $./a.out

This process pid: 18398

Creating new thread...

Done! Thread pid: 18399 /* This is now thread id, available to caller of clone */

getpid(): ad pid: 18399

Inside func.

getpid(): 18398

getppid(): 9638

Looking into /proc/self/status...

Name: a.out

State: R (running)

Tgid: 18398

Pid: 18398

PPid: 9638

TracerPid: 0

Uid: 500 500 500 500

Gid: 500 500 500 500

FDSize: 256

Groups: 7 19 22 80 81 82 83 100 490 500

VmPeak: 1856 kB

VmSize: 1856 kB

VmLck: 0 kB

VmPin: 0 kB

VmHWM: 248 kB

VmRSS: 248 kB

VmData: 168 kB

VmStk: 140 kB

VmExe: 4 kB

VmLib: 1516 kB

VmPTE: 16 kB

VmSwap: 0 kB

Threads: 2

SigQ: 1/14050

SigPnd: 0000000000000000

ShdPnd: 0000000000000000

SigBlk: 0000000000000000

SigIgn: 0000000000000000

SigCgt: 0000000000000000

CapInh: 0000000000000000

CapPrm: 0000000000000000

CapEff: 0000000000000000

CapBnd: ffffffffffffffff

Cpus_allowed: 00000000,000000ff

Cpus_allowed_list: 0-7

voluntary_ctxt_switches: 1

nonvoluntary_ctxt_switches: 0

Inside thread: thread pid = 18398

Inside thread: thread ppid = 9638

请让我知道这可不可以帮你!

标签:linux,multithreading,process

来源: https://codeday.me/bug/20190517/1122666.html

linux clone线程,如何在Linux上使用clone()创建真正的线程?相关推荐

  1. linux系统export,Linux入门进阶 - 如何在Linux中使用export命令

    原标题:Linux入门进阶 - 如何在Linux中使用export命令 来自: Linux迷 链接:https://www.linuxmi.com/linux-export.html Linux ex ...

  2. 如何在Ubuntu上使用MultiSystem创建多启动USB盘

    如何在Ubuntu上使用MultiSystem创建多启动USB盘 介绍 也许还有不少人不知道MultiSystem,它是一个用来在Linux系统中创建多启动usb盘的小型的开源软件.使用这个工具,我们 ...

  3. 如何在Oracle上使用AUTO_INCREMENT创建ID?

    本文翻译自:How to create id with AUTO_INCREMENT on Oracle? It appears that there is no concept of AUTO_IN ...

  4. linux 进程suricata,如何在 Linux 系统上安装 Suricata 入侵检测系统

    随着安全威胁的不断发生,入侵检测系统(IDS)在如今的数据中心环境中显得尤为必要.然而,随着越来越多的服务器将他们的网卡升级到10GB/40GB以太网,对如此线路上的硬件进行计算密集型的入侵检测越来越 ...

  5. linux卸载kodi,如何在Ubuntu上安装Kodi 18 Beta

    Kodi的Beta版周期很长.很棒,因为它有助于将错误排除在生产版本之外,而且还可以保留数月的新功能.值得庆幸的是,Kodi开发人员提供了可供测试和使用的"unstable"软件包 ...

  6. 深度linux安装spotify,如何在 Linux 上使用 snap 安装 Spotify(声破天)

    如何在 Ubuntu Linux 桌面上安装 spotify 来在线听音乐? Spotify 是一个可让你访问大量歌曲的数字音乐流服务.你可以免费收听或者购买订阅,可以创建播放列表.订阅用户可以免广告 ...

  7. docker部署在linux怎么代理,如何在linux 上部署docker

    如何在linux 上部署docker? Docker的三大核心概念:镜像.容器.仓库 镜像:类似虚拟机的镜像.用俗话说就是安装文件. 容器:类似一个轻量级的沙箱,容器是从镜像创建应用运行实例, 可以将 ...

  8. r语言使用linux命令,技术|如何在 Ubuntu 上安装和使用 R 语言

    这个教程指导你如何在 Ubuntu 上安装 R 语言.你也将同时学习到如何在 Ubuntu 上用不同方法运行简单的 R 语言程序. R,和 Python 一样,它是在统计计算和图形处理上最常用的编程语 ...

  9. linux重装eclipse_如何在Linux系统上安装Eclipse

    如何在Linux系统上安装Eclipse 作为Java程序员,需要在Linux系统上安装Eclipse,很多人不知要如何安装,在安装Eclipse前,还需安装JDK,下面小编就给大家介绍下Linux如 ...

最新文章

  1. tomcat日志切割
  2. 【源码解析】hashMap源码跟进
  3. 5-10transformation中部分函数使用
  4. 视频直接变漫画!GAN又有了新玩法 | Demo+代码+论文
  5. android wifi控制手机屏幕,安卓手机屏幕无线投射到电脑+反向控制
  6. 51单片机入门(4)蜂鸣器(无源+有源)
  7. 计算机无法加载操作系统,由于关键系统驱动程序丢失或包含错误,因此无法加载操作系统。解决方案...
  8. 三年内人人有FIL,FIL 世界零撸板块引发全球流量狂潮!
  9. defaults(default是什么职位)
  10. 黑产系列01-如何发现黑产情报
  11. AFNetworking get请求与 post 请求操作
  12. matlab函数im2bw_im2bw(matlab中im2bw用法)
  13. Java8 重复注解与类型注解
  14. 视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等
  15. 记:《洛克菲勒留给儿子的38封信》-- 25
  16. 【每日一题】 1319. 连通网络的操作次数
  17. offset如何使用
  18. 【AFSA TSP】基于matlab改进的人工鱼群算法求解旅行商问题【含Matlab源码 1479期】
  19. 世窗信息IPO被终止:曾计划募资约7亿元,保荐人已被立案调查
  20. Java如何获取JSON数据中的值 备忘

热门文章

  1. 【我解C语言面试题系列】003 死循环格式问题小结?
  2. String.prototype 几个简洁的字符处理函数 (转)
  3. Windows消息机制疑问探究
  4. C#中使用OpenGL(API)创建OpenGL渲染环境
  5. MFC获取键盘光标和鼠标光标所在控件的ID
  6. pythontry参数_Python ——Try Except
  7. element中el-upload和vue-cropper结合实现上传头像裁剪大小
  8. python文件可以包括任何数据内容_python 文件数据合并(数据行不对应)?
  9. oracle行迁移实验,Oracle 行迁移 amp; 行链接的检测与消除
  10. 【296天】我爱刷题系列055(2017.11.28)